2つのラベル間のgrepが-zオプションで機能しないのはなぜですか?どうすれば修正できますか?

2つのラベル間のgrepが-zオプションで機能しないのはなぜですか?どうすれば修正できますか?

この場合:

$ cat t01.txt
xxxyyyzzz

$ cat t01.txt | grep -Po '(?<=xxx).*(?=zzz)'

結果:

yyy

これは予想されます。

しかし、この場合は:

$ cat t02.txt
xxx
yyy
zzz

$ cat t02.txt | grep -Pzo '(?<=xxx).*(?=zzz)'

結果:

<nothing>

これは予期しないことです。

理由と回避策は何ですか?

ベストアンサー1

デフォルトでは、.Perl正規表現の改行文字は一致しません。明示的に一致させるか、s正規表現フラグを使用する必要があります。

$ < t02.txt grep -Pzo '(?<=xxx\n).*\n(?=zzz)'
yyy
$ < t02.txt grep -Pzo '(?s)(?<=xxx).*(?=zzz)'

yyy

たとえば、参照してください。perlreマニュアルページ:

「メタ文字」セクションで:

.   Match any single character except newline    Not in []
    (under /s, includes newline)

そして「修正者」から:

s
文字列を1行として扱います。つまり、"."通常は一致しないすべての文字、改行文字まで一致するように変更します。

おすすめ記事