複数行を含むファイルがあります。次のパターンを含む行を探しています。
\[.*<.*>.*\]
つまり、<something>
[]の間の行が必要です。例は次のとおりです。
Line with [ <matching>|<pattern>]
A line <that> does[not]<match>[]
But [this[<should>]be matched] too
[match [me] <buddy>]
<>の間に許可される唯一の文字は英数字と下線です。
上記の正規表現と怠惰なバージョンを試しましたが、うまくいかないようです。正しい正規表現は何ですか?
答え1
[
、]
ペアが常に一致し、交差しておらず、その[...]
オプションをサポートしている<...>
場合(PCREサポートでビルドするときにGNUが行うように)、次のことができます。grep
-P
grep
grep -P '>(?!((?:[^]]|\[(?1)\])*)$)'
つまり、>
次を探しています。いいえその後、一致する[...]
ペアだけが出ます。 PCREの再帰的一致メカニズムを使用してください(?1)
。
答え2
POSIXlyでは、次のことができますsed
。
sed '
h; # make a copy of the pristine line on the hold space
:1
/\[[^]]*<[^]]*>[^]]*]/{
# found a [...<x>...]
g; # retrieve our saved copy and branch off
b
}
s/\[\([^]]*\)]/\1/g; # remove inner [...]s
# and loop if that s command was successful
t1
# no [...] left to remove, discard this line.
d'
つまり、ペアの1つが見つかる[...]
まで内側からペアが削除されます。<...>
(Solaris または非常に古いシステムでは、Solaris sed は行の先頭でのみコメントを受け入れるため、コメントを削除してください.)
答え3
遅延一致(-P AFAIUが必要)を含むこのパターンは私に適しています。
grep -P '\[[^\]]*?<.*>.*?\]'
答え4
私は次の解決策を思いついた。
grep -P '\[[^.\]]*<.*>[^.\[]*\]' filename
つまり、次の制約に従って[と]のペアを<と>のペアと一致させます。
- []は<>の前に来てはいけません。 "[^.\]]*"の前後には角かっこを閉じるか開けます。
- <>の中には少なくとも1つの文字が必要です。
このソリューションは、怠惰な数量子を使用する正規表現よりもはるかに高速です。