【问题标题】:Regular expression not containing 101正则表达式不包含 101
【发布时间】:2016-01-17 09:09:33
【问题描述】:

我came across不包含101的正则表达式如下:

0∗1∗0∗+(1+00+000)∗+(0+1+0+)∗

我无法理解作者是如何提出这个正则表达式的。所以我只是想到了不包含101的字符串:

01000100

我似乎上面的字符串不会被上面的正则表达式匹配。但我不确定。所以尝试翻译成等效的 pcre 正则表达式on regex101.com,但在那里也失败了(可以看出我的正则表达式甚至不匹配包含单个 1 的字符串。

我的翻译有什么问题?上面的正则表达式确实正确吗?如果不是,那么正确的正则表达式是什么?

【问题讨论】:

  • 问题:拥有一个匹配包含 101的字符串然后只保留不匹配的字符串的正则表达式不是更容易吗?
  • 那个字符串是matched。需要匹配不包含101的字符串吗?
  • 您的问题中+ 的含义看起来不是很清楚。对我来说,似乎+ 与数字在同一行中的意思是通常表示为|。你不是这样翻译的。

标签: regex


【解决方案1】:

这里有一个更短的表达式^0*(1|00+)*0*$

https://www.regex101.com/r/gG3wP5/1

解释:

  • (1|00+)* 我们可以混合 0 和 1,只要 0 成组出现即可
  • ^0*...0*$ 我们可以在前缀/后缀中添加任意数量的零

原始正则表达式的直接翻译就像

^(0*1*0*|(1|00|000)*|(0+1+0+)*)$

更新
这似乎是上述正则表达式的人为复杂版本:

  • (1|00|000)* 与 (1|00+)* 相同
    • 这几乎是解决方案,但它不匹配字符串0、01..和..10
  • 0*1*0* 不匹配内部带有101 的字符串,但匹配0 和一些01.. 和..10
    • 我们仍然需要匹配01.. 和..10 里面混合了0 和1 的那些,例如01001.. 或 ..10010
  • (0+1+0+)* 匹配剩余的一些情况,但仍有一些有效字符串不匹配
    • 例如10010 是不是所有情况都匹配的最短字符串。

所以,这个解决方案过于复杂且不完整。

【讨论】:

  • 我认为这个应该是这个家庭作业的标准解决方案,而不是原始的正则表达式,这对于后台工程来说非常复杂。我猜原始正则表达式的作者缺乏洞察力,即“只要零出现在组中,我们就可以混合零和一”
  • @ead ,我并没有试图简化正则表达式或任何东西,我试图通过不知道正则表达式量词中元字符的变化来显示 OP 出错的地方:),如果这是关于regex that do not match strings with 101 的问题,答案会有所不同:)
  • 是的,您的正则表达式比幻灯片中给出的更直观。只是想知道您是否也可以解释幻灯片正则表达式背后的逻辑......?
  • 你可以减少所需的步骤,如果你这样写你的模式:^0*(?:1*0{2,})*1*0*$
【解决方案2】:

阅读 regex101 右侧选项卡中的说明,它会告诉您正则表达式的作用(我认为您误解了列表运算符的作用),在列表运算符([)内,其他字符(例如 ()赢了'不再是元字符,因此表达式 [(0*1*0*)[1(00)(000)] 将等同于 [01()*[],这意味着它匹配 0 or 1 or ( or ) or [

正则表达式0∗1∗0∗+(1+00+000)∗+(0+1+0+)∗ 的正确翻译 如下:

^((?:0*1*0*)|(?:1|00|000)*|(?:0+1+0+)*)$

regex101

Debuggex Demo

你的正则表达式 [(0*1*0*)[1(00)(000)]*(0+1+0+)*] 做了什么:

[(0*1*0*)[1(00)(000)]* -> matches any of characters 0,(,),*,[ zero or more times followed by

(0+1+0+)* --> matches the pattern 0+1+0+ 0 or more times followed by ] --> matches the character ]

所以你的表达式相当于

[([)01](0+1+0+)*] 不是正则表达式来匹配不包含101的字符串

【讨论】:

  • 是的,谢谢,我不知道[],不允许使用元字符。我在想[] 就像“任何字符出”,所以只需在() 中放入多个字符序列来制作“任何单词出”。可怜的我。
【解决方案3】:

0* 1* ( (00+000)* 1*)* (ε+0)

我认为这个表达式涵盖了所有情况,因为 --
除了 1 之外的任何数字都可以分解为组成部分 2 和 3,即任何数字 n=2*i+3*j。所以除了一个0之外,两个连续的1之间可以有任意数量的0。因此,无法获得101。

ε+0 表示以一个 0 结尾的表达式。

【讨论】:

    【解决方案4】:

    语言不包含101作为子字符串的RE也可以写成(0*1*00)*.0*.1*.0*

    这可能比你使用的更小。尝试利用它。

    【讨论】:

      【解决方案5】:

      我得到 (0+10)1 的正则表达式。 (看起来很简单:P)

      我只是考虑了所有情况。

      您认为两个 1 我们必须以连续的 1 结束 案例一:11111111111111... 案例2:0000000011111111111111...(一旦我们取两个1,我们就不能接受0,所以唯一的机会就是继续1)

      如果您只考虑一个 1,然后是 0 那么,没有问题,在一个 1 之后,我们可以有任意数量的 0。 案例3:00000000 10100100010000100000100000 1111111111

      =>(0*+10*)1 最终答案 (0+10)1.

      感谢您的耐心等待。

      【讨论】:

        猜你喜欢
        • 2019-01-30
        • 1970-01-01
        • 2020-02-06
        • 1970-01-01
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-13
        相关资源
        最近更新 更多