匹配分隔符之间的正则表达式

匹配分隔符之间的正则表达式

我有一个包含几行不同行的文件。我正在寻找包含(或多或少)这样的模式的行:

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

换句话说,我想要<something>[] 之间的行。示例可能是:

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

<> 之间允许的唯一字符是字母数字字符和下划线。

我已经尝试了上面的正则表达式及其惰性版本,但它似乎不起作用。什么是正确的正则表达式?

答案1

如果您的[,]对始终匹配​​,并且您不与 , 交叉[...]<...>并且您grep支持该-P选项(就像grep使用 PCRE 支持构建时的 GNU 一样),您可以执行以下操作:

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. <> 内必须至少有一个字符。

该解决方案也比带有惰性量词的正则表达式快得多。

相关内容