正则数为0和1的正则数

时间:2012-04-18 07:13:55

标签: regex

我正在尝试创建一个正则表达式,用于确定字符串(任意长度)是否与正则表达式模式匹配,以使字符串中的0数为偶数,字符串中的1数为偶数。任何人都可以帮我确定一个正则表达式语句,我可以尝试用它来检查这个模式的字符串吗?

8 个答案:

答案 0 :(得分:8)

完全重新阐述了我的答案以反映所有变化:

这个正则表达式将匹配所有字符串只有零和1,只有相等数量的那些

^(?=1*(?:01*01*)*$)(?=0*(?:10*10*)*$).*$

here on Regexr

我在positive lookahead assertions工作。前瞻性断言的一大优势是,它检查完整的字符串,但没有匹配,所以两个先行都开始从开始检查字符串,但是对于不同的断言。

  1. (?=1*(?:01*01*)*$)会检查等量的0(包括0)

  2. (?=0*(?:10*10*)*$)检查等量的1(包括0)

  3. .*确实匹配字符串

  4. 那些先行检查:

    (?=
        1*    # match 0 or more 1
        (?:   # open a non capturing group
            0     # match one 0
            1*    # match 0 or more 1
            0     # match one 0
            1*    # match 0 or more 1
        )
        *     # repeat this pattern at least once
        $     # till the end of the string
    )
    

答案 1 :(得分:4)

对于偶数组0,您可以使用以下正则表达式来确保0的数量是偶数。

^(1*01*01*)*$

但是,我认为问题是偶数个0和偶数个1。由于可以为此问题构造非确定性有限自动机(NFA),因此解决方案是常规的并且可以使用正则表达式来表示。 NFA通过下面的机器表示,S1是开始/退出状态。

S1 ---1----->S2
|^ <--1----- |^
||           ||
00           00
||           ||
v|           v|
S3----1----->S4
  <---1------

从那里开始,有一种方法可以将NFA转换为正则表达式,但是从我的计算过程开始已经有一段时间了。下面的一些注释似乎有助于解释将NFA转换为正则表达式所需的步骤。

http://www.cs.uiuc.edu/class/sp09/cs373/lectures/lect_08.pdf

答案 2 :(得分:4)

所以,我已经找到了解决问题的方法:

(11+00+(10+01)(11+00)\*(10+01))\*

答案 3 :(得分:1)

再 - 更新


试试这个: [查看此演示:http://regexr.com?30m7c]

^(00|11|0011|0110|1100|1001)+$

提示:

偶数可以被2整除,因此 - 在二进制中 - 它们总是以零结尾(0

答案 4 :(得分:1)

不是正则表达式(这可能是不可能的,虽然我无法证明:通过泵浦引理的矛盾证明失败),但“正确”的解决方案是避免复杂和低效的正则表达式并使用像(在Python中)的东西:

def even01(string):
     return string.count("1") % 2 == 0 and string.count("0") % 2 == 0

或者,如果字符串必须只包含10 s:

import re
def even01(string):
     return not re.search("[^01]",string) and \
            string.count("1") % 2 == 0 and string.count("0") % 2 == 0

答案 5 :(得分:1)

^(0((1(00)*1)*0|1(11|00)*01)|1((0(11)*0)*1|0(11|00)*10))*$

如果我没有忽略任何事情,那么只使用基本的正则表达式运算符(*^匹配任何比特字符串,其中0的数量是偶数,1的数量是偶数,$)。如果这样写的话,它会更容易看出它是如何工作的:

^(0((1(00)*1)*0
   |1(11|00)*01)
 |1((0(11)*0)*1
   |0(11|00)*10))*$

以下测试代码应说明正确性 - 我们将模式匹配的结果与一个函数进行比较,该函数告诉我们字符串是否具有偶数0和1。测试长度为16的所有位串。

import re

balanced = lambda s: s.count('0') % 2 == 0 and s.count('1') % 2 == 0

pat = re.compile('^(0((1(00)*1)*0|1(11|00)*01)|1((0(11)*0)*1|0(11|00)*10))*$')

size = 16
num = 2**size
for i in xrange(num):
    binstr = bin(i)[2:].zfill(size)
    b, m = balanced(binstr), bool(pat.match(binstr))
    if b != m:
        print "balanced('%s') = %d, pat.match('%s') = %d" % (binstr, b, binstr, m)
        break
    elif i != 0 and i % (num / 10) == 0:
        # Python 2's `/` operator performs integer division
        print "%d percent done..." % (100 * i / num + 1)

答案 6 :(得分:0)

如果你试图解决中的同一个句子(以^开头并以$结尾),你就会陷入困境。 : - )

你可以确保你有偶数0(^(1*01*01*)*$,如@ david-z所述)你可以确保你有偶数1秒:

^(1*01*01*)*$|^(0*10*10*)*$

它也适用于长度较短的字符串,例如“00”或“101”,都是有效的字符串。

答案 7 :(得分:0)

I have also been working on lookaheads and lookbacks in my spare time, and using lookahead the problem can be solved while taking also account for the single 1s and/or the single 0s. So, the expression should also work for 11,1111,111111,... and also for 00,0000,000000,....

^(((?=(?:1*01*01*)*$)(?=(?:0*10*10*)*$).*)|([1]{2})*|([0]{2})*)$

Works for all cases. So, if the string consists of only 1s or only 0s:

([1]{2})*|([0]{2})*

If it contains a mix of 0s and 1s, the positive lookahead will take care of that.

((?=(?:1*01*01*)*$)(?=(?:0*10*10*)*$).*

Combining both of them, it takes into account all string with even number of 0s and 1s.