구분 기호 간의 정규식 일치

구분 기호 간의 정규식 일치

여러 줄이 포함된 파일이 있습니다. 다음과 같은 패턴이 포함된 행을 찾고 있습니다.

\[.*<.*>.*\]

즉, <something>[] 사이의 행을 원합니다. 예는 다음과 같습니다.

Line with [ <matching>|<pattern>]
A line <that> does[not]<match>[]
But [this[<should>]be matched] too
[match [me] <buddy>]

<> 사이에 허용되는 유일한 문자는 영숫자와 밑줄입니다.

위의 정규식과 게으른 버전을 시도했지만 작동하지 않는 것 같습니다. 올바른 정규식은 무엇입니까?

답변1

[, ]쌍이 항상 일치하고 와 교차하지 않으며 [...]해당 옵션을 지원하는 <...>경우 ( PCRE 지원으로 빌드할 때 GNU가 하는 것처럼 ) 다음을 수행할 수 있습니다.grep-Pgrep

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

즉, 다음 제약 조건에 따라 [ 및 ] 쌍을 < 및 > 쌍과 일치시킵니다.

  1. []는 <> 앞에 오면 안 되며 "[^.\]]*" 앞과 뒤에는 대괄호를 닫거나 열어야 합니다.
  2. <> 안에는 문자가 하나 이상 있어야 합니다.

이 솔루션은 게으른 수량자를 사용하는 정규식보다 훨씬 빠릅니다.

관련 정보