【问题标题】:Why doesn't the regex ^([0|1]1)+$ match the string "111"?为什么正则表达式 ^([0|1]1)+$ 不匹配字符串“111”?
【发布时间】:2014-09-20 16:17:00
【问题描述】:

我正在尝试编写一个正则表达式来匹配二进制字符串,其中每个奇数字符都是1

我想出了这个:

^([0|1]1)+$

我的逻辑:

^ 匹配行首

( 启动捕获组

[0|1] 匹配 01(因为第 0 位是偶数)

1 前一个字符(01)后面必须跟 1

+ 重复上一个模式一次或多次

$ 匹配行尾

所以按照我的逻辑,上面的正则表达式应该匹配二进制字符串,其中每隔一个字符(第一个“其他”字符是字符串中的第二个字符)是1

但是,它不能正常工作。例如,字符串111 不匹配。

为什么它不工作,我应该改变什么才能让它工作?

Regex101 Test

【问题讨论】:

  • 字符类中不需要|

标签: regex


【解决方案1】:

如果您需要每个奇数字符都成为1,那么您需要更像这样的东西:

^([01]1)*[01]?$

第一个字符可以是任何字符,下一个字符必须是1,然后重复多次,最后一个字符可以是 0 或 1。

不需要你的字符类中的管道,实际上是让你的正则表达式也匹配一个管道字符。所以完全删除它。您在组中使用管道(即(?: ... )( ... ) 表示交替)。

以上内容也将匹配一个空字符串,因此您可以在开头添加(?=.)以强制匹配至少1个字符(即^(?=.)([01]1)*[01]?$

以上将匹配您拥有的位置(x 是 0 或 1):

x
x1
x1x
x1x1
x1x1x
x1x1x1

等等

您当前的正则表达式正在尝试匹配偶数个字符。您重复组 ([0|1]1) 精确匹配 2 个字符(不多不少),因此整个匹配的长度将是 2 的倍数。

在末尾添加可选的[01] 允许匹配奇数个字符的字符串。

【讨论】:

  • 也许最后的1 应该是可选的。
  • @MattBall 不,我完全误解了这个问题。现在修好了。
  • 这是这些答案中(非常)少数正确的表达方式之一。但显然反对者​​已经走了,不会推翻他们的投票......
  • @xsc 感谢您的支持。我看到 NPE 也刚刚更改了他的正则表达式,这和我的一样。是的,人们投了反对票并忘记了,我几乎可以肯定他们自己不理解这个问题^^;
【解决方案2】:

您的正则表达式仅适用于偶数长度的字符串。 [01]1 分别匹配一个字符,因此您的捕获组匹配 2 个字符。

这会修改您的正则表达式以接受奇数长度的字符串:

^([01](1|$))+$

【讨论】:

  • +1 哎呀,打败我的。不知道为什么人们投票反对。他们投票赞成或反对,去图=/
【解决方案3】:

首先,[0|1] 应为 [01]。否则,您有一个匹配的字符组,0|1

现在,[01]1 正好匹配两个字符。因此([01]1)+ 无法匹配长度不是二的倍数的字符串。

要使其适用于奇数长度的输入,请将正则表达式更改为

^(([01]1)+[01]?|1)$

【讨论】:

  • 不是反对者,但可能是因为这部分 OPs 问题:“(因为第 0 位是偶数)”?
  • @xsc:谢谢,但我不太明白。您能否发布一个具体的反例,说明这个正则表达式没有做您认为应该做的事情?
  • 不是拒绝投票者(哈哈,我是第一个连续收到两份 DV 的人),但 101 匹配,而第二个字符应该是 1
  • @NPE:它接受 101,但奇数索引处的每个字符都应为 1。OP 声明第一个位置的索引为 0,因此第二个字符可能不是 0。
  • @xsc:谢谢,我想我现在关注了。
【解决方案4】:

你可以使用这个模式:

^1?([01]1)+$|^1$

^(1?([01]1)+|1)$

要处理奇数或偶数位数,您需要在开头添加可选的1?。为确保至少有一个数字,您不能对组使用* 量词,否则模式可以匹配空字符串。这就是为什么,您需要将+ 用于组并添加单个1 的情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 2019-05-06
    • 1970-01-01
    相关资源
    最近更新 更多