Регулярное выражение, позволяющее вводить буквенно-цифровые символы, не более одного пробела и т. Д.

Я открываю этот поток, который действительно похож на другой, но я не могу выяснить проблему: у меня есть поле ввода, в котором можно использовать буквенно-цифровую строку с необязательным уникальным пробелом в качестве разделителя, а затем необязательную другую буквенно-цифровую строку и т. Д.... Я нахожу это регулярное выражение:

^([0-9a-zA-z]+ ?)*$

Оно работает! Но производительность действительно плохая, как только у меня есть 2 последовательных пробела в длинном предложении, и эти 2 пробела расположены далеко в предложении. В приведенном ниже примере результат будет хорошим через полсекунды, если я поставлю 2 пробела в начале предложения. Но это длится 10 секунд или больше, если находится далеко.

dzdff5464zdiophjazdioj TTTTTTTTT zoddzdffdziophjazdioj TTTTTTTTT zoddzdffdzdff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zoddzdfff TTTTT zo999 ddzdfff TTTTT zoddzdfff TTTTT zoddzdff

2 пробела после 999, Есть ли у вас какие-либо идеи или предложения по улучшению этого регулярного выражения?

Спасибо и всего наилучшего

PF

PS: вы можете проверить проблему, как только вы введете недопустимый символ в строке, а не 2 пробела.

РЕДАКТИРОВАТЬ: другой пример: 12345678901234567890' ==> 20 симв. + 1 недопустимый символ => Результат немедленный Добавить 5 действительных символов. и это длится 5 секунд, чтобы выполнить регулярное выражение! 1234567890123456789012345'

2 ответа

Решение

Я предлагаю изменить выражение на что-то вроде этого:

(?i)^[0-9a-z]+(?:\s[0-9a-z]+)*$

введите описание изображения здесь

Это функционально похоже на то, что оно будет соответствовать всем буквенно-цифровым символам, которые разделены одним пробелом. Основное отличие состоит в том, что я переместил начальную проверку слова в начало выражения, а затем создал группу без захвата. (?:...) для оставшихся пробелов слова.

Группы без захвата (?:...) быстрее, чем захватывать группы (...) потому что движку регулярных выражений не нужно сохранять совпадающие значения. И перемещая пространство \s перед группой слов в повторяющихся словах движку не нужно проверять первый символ в группе, включенный в класс символов.

У вас также есть опечатка в вашем классе персонажей [0-9a-zA-z] последний z должно быть в верхнем регистре. это A-z формат, скорее всего, будет иметь некоторые странные неожиданные результаты. В моем выражении я просто добавил (?i) в начале, чтобы заставить механизм регулярных выражений перейти в режим без учета регистра, и я опустил класс символов в [0-9a-z],

В моем тестировании я вижу, что ваше выражение ^([0-9a-z]+ ?)*$ Обработка вашего образца текста занимает около 0,03 секунды с двумя дополнительными пробелами в конце. Мое рекомендованное выражение завершает тот же тест примерно за 0,000022 секунды. ВАУ, это удивительная дельта.

Это более простое регулярное выражение, использующее \w ( слово класс):

^([\w]+(\s*))$

Тестовое задание

Это мгновенно в JavaSript

var input = "dzdff5464zdiophjazdioj ttttttttt zoddzdffdziophjazdioj ttttttttt  zoddzdffdzdff ttttt zoddzdfff ttttt zoddzdfff ttttt zoddzdfff ttttt  zoddzdfff ttttt zoddzdfff ttttt zoddzdfff ttttt zoddzdfff ttttt  zoddzdfff ttttt zo999  ddzdfff ttttt zoddzdfff ttttt zoddzdff";

var re = /([\w]+(\s*))/g;

console.log(input.replace(re, "boo"));
Другие вопросы по тегам