以下のテキストファイルがあります。
(111)1111111
(111)-111-1111
(111)111-1111
111.111.1111
正規表現とsedを使用してグループキャプチャを練習するために使用します。ファイルに対して実行するコマンド(testと呼ばれる)は次のとおりです。
sed 's/(?\(\d(3}\)[-.]?\(\d{3}\)[-.]?\(\d{4}\)/\1\2\3' test > output
予想される出力は各行のすべて1です。しかし、私が得るのは、変更がないファイル全体です。何が間違っていますか?
答え1
標準の基本正規表現では、(?\(\d(3}\)[-.]?
これは次のことを意味します。
a literal left parenthesis
a literal question mark
(start of a group)
a literal character 'd'
a literal left parenthesis
the number '3'
a literal closing brace
(end of group)
a dash or a dot
a question mark
つまり、次のように印刷されますx
。
echo '(?d(3}-?' |sed 's/(?\(\d(3}\)[-.]?/x/'
sed -E
ERE(拡張正規表現)を有効にしてから、グループ化とリテラルの括弧で囲むためにおよびを(
使用する可能性が高いです。)
\(
\)
また、これは\d
標準正規表現ではなくPerl正規表現の一部であり、GNU sedはいくつかのエスケープをサポートしていますが、標準ではありません(私の考えではありません)。同様に、GNU sedはEREの意味を表現するためにBREでこれをサポートしていますが、これは標準ではありません。\X
\d
\?
?
これらすべてを念頭に置いてください。
$ echo '(123)-456-7890' | sed -E 's/\(?([0-9]{3})\)?[-.]?([0-9]{3})[-.]?([0-9]{4})/\1\2\3/'
1234567890
無差別代入で、数値を除くすべての項目を削除することもできます。
$ echo '(123)-456-7890' | sed -e 's/[^0-9]//g'
1234567890
(もちろん、次のような(123)-4.5-6-7a8b9c0
ことも許可されています...)
また見なさい:
答え2
awkコマンドでもできます
echo "123-45-6789-10101"| awk '{gsub("[^0-9]","",$1);print }'
出力
12345678910101
答え3
イルカチョの説明正規表現がうまくいかない理由をお勧めしますsed
(サポートされていない方言です)。
存在しない文字のみを削除する別のアプローチは次のとおりです1
。
sed 's/[^1]//g' file
グループを使用するには、次のようにします。
sed -E 's/([^1]*)(1+)([^1]*)/\2/g' file
つまり、両側で空にすることができる1以外の文字列で区切られた空でない1文字列を一致させ、すべてを一致する1文字列に置き換えます。
すべての数字を処理するには、とに変更し1
ます。[0-9]
[^1]
[^0-9]