我正在尝试创建一个正则表达式,用于确定字符串(任意长度)是否与正则表达式模式匹配,以使字符串中的0数为偶数,字符串中的1数为偶数。任何人都可以帮我确定一个正则表达式语句,我可以尝试用它来检查这个模式的字符串吗?
答案 0 :(得分:8)
完全重新阐述了我的答案以反映所有变化:
这个正则表达式将匹配所有字符串只有零和1,只有相等数量的那些
^(?=1*(?:01*01*)*$)(?=0*(?:10*10*)*$).*$
我在positive lookahead assertions工作。前瞻性断言的一大优势是,它检查完整的字符串,但没有匹配,所以两个先行都开始从开始检查字符串,但是对于不同的断言。
(?=1*(?:01*01*)*$)
会检查等量的0(包括0)
(?=0*(?:10*10*)*$)
检查等量的1(包括0)
.*
确实匹配字符串
那些先行检查:
(?=
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
或者,如果字符串必须只包含1
和0
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.