简体   繁体   中英

Regex to NOT match a string with 10 consecutive digits. The digits may be separated by white space. All other string return a match

I have a codepen with 5/7 unit tests passing. Stuck on strings starting with non-digit characters.

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));

With this regex the following strings pass the unit tests

  • "abc123" true
  • "1234567890" true
  • "123456789" true
  • "123 456 789 123" true
  • "1234567890efg" true

These fail the unit tests

  • "abc1234567890" false
  • "abc1234567890efg" false

Note: /^\\D{3,}(?!(\\s*\\d\\s*){10,}).*/ passes all the tests but is obviously wrong.

The problem with ^\\D*(?! is that, even if a long digit/space string is found in the negative lookahead, the part matched by \\D will simply backtrack one character once the negative lookahead matches. Eg, when

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

matches

abc1234567890

the \\D* matches ab , and the .* matches c1234567890 . The position between the b and the c is not immediately followed by a long number/space substring, so the match does not fail.

Also, because some digits may come before the 10 consecutive digits, the ^\\D* at the beginning won't be enough - for example, what if the input is 1a01234567890 ? Instead, try

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

This ensures that every position is not followed by (10 digits, possibly separated by spaces).

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

If the digits can only come in a single block (possibly separated by spaces) in the string, your pattern would've worked if you were in an environment which supports possessive quantifiers, which prevent backtracking, eg:

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

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

(but Javascript does not support such syntax, unfortunately)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM