여러 줄이 포함된 파일이 있습니다. 다음과 같은 패턴이 포함된 행을 찾고 있습니다.
\[.*<.*>.*\]
즉, <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'
즉, 쌍 중 하나가 발견될 [...]
때까지 내부부터 쌍이 제거됩니다 .<...>
(Solaris 또는 매우 오래된 시스템에서는 Solaris sed가 줄 시작 부분에서만 주석을 허용하므로 주석을 제거하십시오.)
답변3
지연 일치(-P AFAIU 필요)가 포함된 이 패턴은 나에게 적합합니다.
grep -P '\[[^\]]*?<.*>.*?\]'
답변4
나는 다음과 같은 해결책을 생각해 냈습니다.
grep -P '\[[^.\]]*<.*>[^.\[]*\]' filename
즉, 다음 제약 조건에 따라 [ 및 ] 쌍을 < 및 > 쌍과 일치시킵니다.
- []는 <> 앞에 오면 안 되며 "[^.\]]*" 앞과 뒤에는 대괄호를 닫거나 열어야 합니다.
- <> 안에는 문자가 하나 이상 있어야 합니다.
이 솔루션은 게으른 수량자를 사용하는 정규식보다 훨씬 빠릅니다.