grep-如何仅使用两个字符匹配正则表达式,但每个字符出现的次数相同?

使用 grep,我试图匹配由两个字符组成的行,一个是重复的,然后是另一个,但仅当第一个字符出现的次数等于第二个字符的出现次数时才匹配。

例如,假设我只能匹配两个字符,例如“0”和“1”。现在想象一下,如果有 n 个 '0' 字符,那么后面必须有 n 个 '1' 字符。例如:

  • ''
  • '0011'
  • '000111'
  • '00000000001111111111'

都会匹配。但:

  • '011'
  • '1100'
  • '110001'

不匹配。

我一直在玩捕获组并通过 perldoc 搜索有关 grep -P 的更多信息,但还没有找到任何解决我问题的线索 - 至少使用 grep。

给定这些约束,我如何制作 grep 命令来匹配字符串?

编辑:

  • 在此示例中,根据“紧随其后”的限制,0 应位于 1 之前
  • 空字符串也应该是一个匹配案例,因为根据示例限制,当有 n 个 0 时,应该有 n 个 1,因此当有零个 0 时,应该有零个 1。

回答

有关说明的更新,请参阅下面的编辑


这是 Perl one-liner 而不是 grep

perl -wne'print if /^((.)g{-1}+)((.)g{-1}+)$/ and length $1 == length $3' file

匹配的长度比较显然是在正则表达式之外完成的;我不认为它可以在内部很好地完成,而且我认为使用不是正则表达式的代码没有任何问题:)

这与单个字符 ( ab)不匹配,什么是没有意义的,什么似乎被排除在问题之外。锚点 (^$) 使它只能匹配具有两个字符的字符串,这似乎是指定的。

g{-1}是一个相对反向引用。它匹配上次捕获的相同子模式,这是我们需要的,而不是简单的反向引用 ( g1)。

这是需要的,因为g1指的是第一次捕获,括号集最先开始(最左边),也就是整个模式的捕获。(我们可以使用,g2但将它们计算在内是不好的做法。)

这可以通过使用命名引用变得更好,但它也会更加复杂。


编辑   根据澄清,它必须0先是 s 然后是相同数量的1s,并且0-repetitions 计数(所以是空行),1当然还有-repetition (所以01)。这大大简化了问题,因为

perl -wne'print if /^(0*)(1*)$/ and length $1 == length $2' file

01可以制成其可作为外部参数如果需要,可以提供,(所以它可以是任何语法,变量ab等等)。

它在问题的示例输入上按预期打印,因此在输入上 file

0011

000111
00000000001111111111
01

011
1100
110001

它打印

0011

000111
00000000001111111111
01

(输出中的最后一个空行是中间的空行,之后没有更多行匹配)


也就是说,不使用在正则表达式中运行代码的棘手功能,这会使其变得更加复杂。如果您仍然希望使用它,请在 perlre

perlretut中查看它

或者,这也可以使用regex 中的递归来完成,具有相似(或稍低?)的复杂性。


以上是grep-如何仅使用两个字符匹配正则表达式,但每个字符出现的次数相同?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>