Регулярное выражение, чтобы НЕ совпадать со строкой из 10 последовательных цифр. Цифры могут быть разделены пробелом. Все остальные строки возвращают совпадение

#javascript #regex

#javascript #регулярное выражение

Вопрос:

У меня есть codepen с прохождением модульных тестов 5/7. Застрял на строках, начинающихся с нецифровых символов.

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

 var regexString = /^D*(?!(s*ds*){10,}).*/;
 
 var regexString = /^D*(?!(s*ds*){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» true
  • «1234567890» true
  • «123456789» true
  • «123 456 789 123» true
  • «1234567890efg» true

Они не проходят модульные тесты

  • «abc1234567890» false
  • «abc1234567890efg» false

Примечание: /^D{3,}(?!(s*ds*){10,}).*/ проходит все тесты, но явно ошибается.

Комментарии:

1. @Emma Он хочет, чтобы была видна каждая строка в журнале true .

Ответ №1:

Проблема в ^D*(?! том, что, даже если в отрицательном прогнозе найдена длинная строка с цифрами / пробелами, часть, сопоставленная с D , просто отследит один символ, как только совпадет отрицательный прогноз. Например, когда

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

Матчи

 abc1234567890
 

D* совпадения ab и .* совпадения c1234567890 . За позицией между b и c не сразу следует длинная подстрока с числом / пробелом, поэтому совпадение не завершается ошибкой.

Кроме того, поскольку некоторые цифры могут предшествовать 10 последовательным цифрам, ^D* в начале будет недостаточно — например, что, если ввод 1a01234567890 ? Вместо этого попробуйте

 ^(?!.*(ds*){10}).*
 

Это гарантирует, что за каждой позицией не следует (10 цифр, возможно, разделенных пробелами).

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

Если цифры могут входить только в один блок (возможно, разделенный пробелами) в строке, ваш шаблон сработал бы, если бы вы находились в среде, которая поддерживает притяжательные кванторы, которые предотвращают возврат, например:

 ^D* (?!(s*ds*){10,}).*
    ^
 

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

(но Javascript, к сожалению, не поддерживает такой синтаксис)

Комментарии:

1. но ваше регулярное выражение совпадает abc123 … это не должно

2. Я думал, что так и должно быть? { text: 'abc123', ismatch: true} — он хочет, чтобы это было совпадение, потому что в нем нет последовательных строк из 10 цифр / пробелов

3. ох … Я думал, что критерием, основанным на ПО КРАЙНЕЙ мере 10 цифрах, было {10,} — я думаю, это одна из многих вещей, которые OP сделал неправильно: p