-2

我需要使用语言 {0,1} 构造正则表达式

正则表达式应该接受奇数个 0 和奇数个 1

4

3 回答 3

4

整个正则表达式:

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

一种概念化它的方法:

x = (00|11)
y = (10|01)
z = x*yx*yx*

^(z|x)*y(z|x)*$

因为我们正在考虑奇偶校验,而不是计数,所以这可以在正则表达式中完成。该模式x不影响奇偶校验,而该模式y切换奇偶校验。该模式z寻找匹配y(零对奇偶校验的净影响),忽略干预x。那么你只需要一个y

也许一个较短的正则表达式,y用于匹配最后一个奇偶校验开关,可能是:

^(z|x)*yx*$
^(x*yx*yx*|x)*yx*

这是:

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

这尚未经过广泛测试,但我相信它有效。

于 2013-10-27T07:02:54.900 回答
1

不知道你为什么得到这么复杂的答案。此正则表达式将为您工作:

var re = /^(?!(([^0]*0){2})*[^0]*$)(?!(([^1]*1){2})*[^1]*$)[01]+$/

re.test('010'); // false
re.test('011'); // false 
re.test('01'); // true
re.test('10'); // true
re.test('001101'); // true
re.test('00'); // false
re.test('11'); // false

它通过使用负前瞻来确保在仅包含 0 或 1 的字符串中有奇数个 0 跟随和关闭 1 个跟随

现场演示:http: //ideone.com/hvIkx2

于 2013-10-27T09:59:22.090 回答
0

但是,您可以在扩展正则表达式中真正做到这一点。

这个正则表达式支持 iinfinite0|1的字符串。

/(?!^(?:0|10*1)*$)(?!^(?:1|01*0)*$)^[01]+$/

自由间距模式。

/
    (?!              # negative lookahead enables checking both 1 or 0
        ^            # match the whole string
        (?:          # no matching group for efficiency and readability
            0|10*1   # 0 or a pair of  1
        )*           # arbitrary `0`s or double `1`s
        $
    )                # end of the lookahead
    (?!              # negative lookahead enables checking both 1 or 0
        ^            # match the whole string
        (?:          # no matching group for efficiency and readability
            1|01*0   # 1 or a pair of  0
        )*           # arbitrary `1`s or double `0`s
        $
    )                # end of the lookahead
    ^[01]+$
/

这里的要点是:

  1. 偶数0|1可以匹配/(01*0)*/

  2. 零宽度断言可以多次检查字符串

测试

  function makeStr(n) {
    if (n <= 1) { return ['0', '1'];}
    return makeStr(n-1).reduce(function(acc, ele){
      acc.push('0' + ele);
      acc.push('1' + ele);
      return acc;
    }, [])
  }
  function countOdd(str, char) {
    if (char === 0) {
      return str.replace(/[^0]/g, '').length%2 !== 0;
    } else {
      return str.replace(/[^1]/g, '').length%2 !== 0;
    }
  }
  function valid(str) {
    return countOdd(str, 0) && countOdd(str, 1);
  }

  var reg = /(?!^(?:0|10*1)*$)(?!^(?:1|01*0)*$)^[01]+$/

  for (var i = 1; i < 10; i++) {
    makeStr(i).forEach(function(e) {
      if (reg.test(e) !== valid(e)) {
        console.log(e);
      }
    });
  }

测试用例:http: //jsfiddle.net/2MZxf/

在线演示:http: //ysmood.github.io/regex-builder/

代码:N4IgpgHgDiBcIAoD8BCAes2AGAPgRiwCo8BKQgEhOXUzxyz0KzMrQG0GBdAanJABoQAMwA2AQwDmAZzggJAWwEgALhGWyGWLAB0AdloZ7NDPEeNHTuvXhs6r+g5b16QAXyAAAA==

完毕 :)

于 2013-10-27T04:54:38.213 回答