テキストファイルで二重引用符または一重引用符内の文字列を探したいです(テキストファイルは複数行です)。
たとえば、
I have a
test "foo bar1" test2 "foo\"bar2",
"foo 'bar3",
'foo bar4', 'foo \'bar5', 'foo "bar6',
出力されます
foo bar1
foo\"bar2
foo 'bar3
foo bar4
foo \'bar5
foo "bar6
難易度は次のとおりです。
- テキストファイルは複数行です。
- 二重引用符または一重引用符を引用符でエスケープした可能性があります。
- 二重引用符の中に一重引用符を入れることができます。
- 一重引用符の中に二重引用符が含まれる場合があります。
- 引用符はペアで一致する必要があります。
ベストアンサー1
Perlの一致タイムコード補間機能を使用して(??{ match time regex })
この問題を解決できます。デフォルトでは、これが行うことは、一致する参照に基づいて正規表現エンジンがその参照ペアをキャプチャできるように、その参照に対応する有効な正規表現を配置することです。
$ perl -lne '
print substr($&, 1, -2+length($&))
while
/(?:(["'\''])(??{q<(?:[^\\\\>.$1.q<]|\\\\.)*>.$1}))/gx;
' file
結果:
foo bar1
foo\"bar2
foo 'bar3
foo bar4
foo \'bar5
foo "bar6
上記の内容をよりスムーズに書き直すと、次のようになります。
$ perl -lne '
BEGIN {
$genRE = sub {
my $openingQ = shift;
# look in the Notes below for why
qq<(?:[^\\\\${openingQ}]|\\\\.)*>
};
}
print $2
while
/
(["'\'']) (?#: opening quote)
((??{ $genRE->($1) })) (?#: run of in between quote pair stuff)
\1 (?#: corresponding closing quote)
/gx;
' file
メモ::
"........"
マッチ/"[^"]*"/
"...... \"......"
マッチ/"(?:[^\\"]|\\.)*"/
- 一重引用符も似ています。