正则表达式不匹配连续10位数字的字符串。这些数字可以用空格分隔。所有其他字符串返回匹配项

时间:2019-04-17 03:47:56

标签: javascript regex

我有一个通过5/7单元测试的Codepen。卡在以非数字字符开头的字符串上。

https://codepen.io/david-grieve/pen/pBpGoO?editors=0012

var regexString = /^\D*(?!(\s*\d\s*){10,}).*/;

var regexString = /^\D*(?!(\s*\d\s*){10,}).*/;

var tests = [{
    text: 'abc123',
    ismatch: true
  }, {
    text: '1234567890',
    ismatch: false
  }, {
    text: '123456789',
    ismatch: true
  }, {
    text: 'abc1234567890efg',
    ismatch: false
  }, {
    text: '123 456 789 123',
    ismatch: false
  },
  {
    text: 'abc1234567890',
    ismatch: false
  }, {
    text: '1234567890efg',
    ismatch: false
  }
];

console.log(new Date().toString());
tests.map(test => console.log(test.text, regexString.test(test.text) == test.ismatch));

使用此正则表达式,以下字符串通过了单元测试

  • “ abc123”为真
  • “ 1234567890”为真
  • “ 123456789”为真
  • “ 123 456 789 123”为真
  • “ 1234567890efg”为真

这些未通过单元测试

  • “ abc1234567890”错误
  • “ abc1234567890efg”错误

注意:/^\D{3,}(?!(\s*\d\s*){10,}).*/通过所有测试,但显然是错误的。

1 个答案:

答案 0 :(得分:1)

^\D*(?!的问题在于,即使在负前瞻中找到了长数字/空格字符串,与\D匹配的部分也只会 backtrack 一个字符一旦负前瞻匹配。例如,何时

^\D*(?!\d{10,}).*

匹配

abc1234567890

\D*匹配ab,而.*匹配c1234567890bc之间的位置不是立即,后跟一个长数字/空格子字符串,因此匹配不会失败。

此外,由于某些数字可能会在连续的10位数字之前出现,因此开头的^\D*是不够的-例如,如果输入是{{1} }?而是尝试

1a01234567890

这可以确保每个位置都不会跟随(10位数字,可能用空格分隔)。

https://regex101.com/r/v7t4IC/1

如果数字只能出现在字符串的单个块中(可能用空格隔开),那么如果您在支持 possitive 量词的环境中使用该模式就可以了,这可以防止回溯,例如:

^(?!.*(\d\s*){10}).*

https://regex101.com/r/eGdw2l/1

(不幸的是Javascript不支持这种语法)