最短一致をgrepしたいのですが、パターンは次のようになります。
<car ... model=BMW ...>
...
...
...
</car>
...は任意の文字を意味し、入力は複数行です。
欲張りでない(または怠laな)マッチを探しています。正規表現で貪欲でない一致を取得するには、数量詞の後に修飾子?
を使用する必要があります。たとえば、.*
を.*?
に変更できます。
デフォルトでは、grep
は貪欲でない修飾子をサポートしていませんが、grep -P
を使用してPerl構文を使用できます。
実際、.*?
はPerl
でのみ機能します。同等のgrep拡張正規表現構文がどうなるかはわかりません。幸いなことに、grepでPerl構文を使用できるので、grep -P
は機能しますが、egrep
と同じgrep -E
は機能しません(貪欲になります)。
参照: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep
grep
の貪欲でない一致には、否定文字クラスを使用できます。言い換えれば、ワイルドカードを避けるようにしてください。
たとえば、ページコンテンツからjpegファイルへのすべてのリンクを取得するには、次を使用します。
grep -o '"[^" ]\+.jpg"'
複数行に対処するには、最初にxargs
を介して入力をパイプ処理します。パフォーマンスのために、 ripgrep
を使用します。
このスレッドで何かを試した後に動作する私のgrep:
echo "hi how are you " | grep -shoP ".*? "
必ず各行にスペースを追加してください
(私は単語を吐き出すための行ごとの検索でした)
簡単な答えは、次の正規表現を使用することです。
(?s)<car .*? model=BMW .*?>.*?</car>
(少し)より複雑な答えは:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
これにより、次のテキストでcar1とcar2を一致させることができます。
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>