正規表現内の角括弧をgrepで一致させるにはどうすればよいですか? 質問する

正規表現内の角括弧をgrepで一致させるにはどうすればよいですか? 質問する

[と の両方をgrep で一致させようとしています]が、 の一致にしか成功しません[。どのように試しても、 を正しく一致させることができないようです]

以下にコードサンプルを示します。

echo "fdsl[]" | grep -o "[ a-z]\+" #this prints fdsl
echo "fdsl[]" | grep -o "[ \[a-z]\+" #this prints fdsl[
echo "fdsl[]" | grep -o "[ \]a-z]\+" #this prints nothing
echo "fdsl[]" | grep -o "[ \[\]a-z]\+" #this prints nothing

編集: 私がこれを実行する必要がある元の正規表現は次のとおりです:

echo "fdsl[]" | grep -o "[ \[\]\t\na-zA-Z\/:\.0-9_~\"'+,;*\=()$\!@#&?-]\+" 
#this prints nothing

注:私はすべての回答を試しましたこれ投稿しましたが、この特定のケースでは機能しませんでした。また、内部で括弧を使用する必要があります[]

ベストアンサー1

によるとBRE/ERE 括弧式POSIX 正規表現仕様のセクション:

  1. [...] 右角括弧 ( ']') は、リストの最初に出現した場合 (先頭にサーカムフレックス ( '^') がある場合はその後ろに出現)、その特別な意味を失い、角括弧式内でそれ自体を表します。それ以外の場合、照合記号 ( など"[.].]") 内に表示されるか、照合記号、等価クラス、または文字クラスの終了右角括弧でない限り、角括弧式を終了します。特殊文字'.''*''[''\'(それぞれピリオド、アスタリスク、左角括弧、およびバックスラッシュ) は、角括弧式内ではその特別な意味を失います。

そして

  1. [...] 角括弧式で'-'との両方を指定する場合']'、 は角括弧式内で最初(がある場合は の']'後)に配置され、 は最後に配置されます。'^''-'

したがって、正規表現は次のようになります。

echo "fdsl[]" | grep -Eo "[][ a-z]+"

E量指定子をサポートする ERE を使用することを指定するフラグに注意してください++量指定子は BRE (デフォルト モード) ではサポートされていません。

Mike Holtの回答にある"[][a-z ]\+"エスケープされた解決策は+、GNU grepで実行されるため機能します。文法を拡張して、\+1回以上繰り返すことを意味するようにサポートします。. 実はPOSIX 標準による未定義の動作(つまり、実装によって意味のある動作を提供してそれを文書化したり、構文エラーをスローしたりできるということです)。

コードがGNU環境でのみ実行できるという前提で問題ない場合は、Mike Holtの回答を使用してもまったく問題ありません。sed例として、BREを使用する場合は、POSIXsed(ERE に切り替えるフラグがない)、定義された量指定子が のみである POSIX BRE では、単純な正規表現を記述することさえ面倒です*

元の正規表現

は入力ファイルを 1 行ずつ読み込み、その行が正規表現と一致するかどうかをチェックすることに注意してください。したがって、元の正規表現で flag をgrep使用しても、正規表現は行をまたいで一致できないため、 は常に冗長になります。P\n

可能ではあるが水平タブに一致それなし PフラグPこのタスクにはフラグを使用する方が自然だと思います。

次の入力があるとします:

$ echo -e "fds\tl[]kSAJD<>?,./:\";'{}|[]\\!@#$%^&*()_+-=~\`89"
fds     l[]kSAJD<>?,./:";'{}|[]\!@#$%^&*()_+-=~`89

質問の元の正規表現は、少し変更するだけで機能します (+最後にエスケープを解除します)。

$ echo -e "fds\tl[]kSAJD<>?,./:\";'{}|[]\\!@#$%^&*()_+-=~\`89" | grep -Po "[ \[\]\t\na-zA-Z\/:\.0-9_~\"'+,;*\=()$\!@#&?-]+"
fds     l[]kSAJD
?,./:";'
[]
!@#$
&*()_+-=~
89

\nただし、(上で説明したように冗長であるため) その他の不要なエスケープは削除できます。

$ echo -e "fds\tl[]kSAJD<>?,./:\";'{}|[]\\!@#$%^&*()_+-=~\`89" | grep -Po "[ \[\]\ta-zA-Z/:.0-9_~\"'+,;*=()$\!@#&?-]+"
fds     l[]kSAJD
?,./:";'
[]
!@#$
&*()_+-=~
89

おすすめ記事