regex.test VS string.match, щоб дізнатися, чи відповідає рядок звичайному виразу


287

Я багато разів використовую функцію string, matchщоб дізнатися, чи відповідає рядок звичайному виразу.

if(str.match(/{regex}/))

Чи є різниця між цим:

if (/{regex}/.test(str))

Вони, здається, дають однаковий результат?


4
це найкращі тести, які ви знайдете jsperf.com/regexp-test-vs-match-m5
ajax333221

@ ajax333221. Дякую за jsperf, але я не впевнений, що він хороший. Регекс збігається з використанням групи відповідності, яка не потрібна при пошуку булевого значення.
gdoron підтримує Моніку

Відповіді:


440

Основне використання

Спочатку давайте подивимося, що робить кожна функція:

regexObject . тест ( рядок )

Виконує пошук відповідності між звичайним виразом та заданим рядком. Повертає істинне або хибне .

рядок . матч ( RegExp )

Використовується для отримання відповідностей при зіставленні рядка з регулярним виразом. Повертає масив із збігами або nullякщо таких немає.

Оскільки nullоцінює false,

if ( string.match(regex) ) {
  // There was a match.
} else {
  // No match.
} 

Продуктивність

Чи є якась різниця щодо продуктивності?

Так . Цю коротку замітку я знайшов на сайті MDN :

Якщо вам потрібно знати, чи відповідає рядок рядку регулярного виразу, використовуйте regexp.test (рядок).

Чи різниця значна?

Відповідь ще раз ТАК ! Цей jsPerf, який я склав, показує, що різниця становить ~ 30% - ~ 60% залежно від браузера:

тест проти відповідності |  Тест на продуктивність

Висновок

Використовуйте, .testякщо хочете швидший булевий чек. Використовуйте .matchдля отримання всіх збігів при використанні gглобального прапора.


5
Не надто здивований, оскільки функція string повинна перевертати речі, а потім створити масив, якщо є відповідність. Схоже, я продовжуватиму використовувати .test(). :)

22
Мої два центи: продуктивність завищена. Будь-який варіант може зробити ~ 15 000 операцій у мерехтінні монітора, тому, якщо ви не робите масовий регекс на стороні клієнта, швидкість не є важливою. Звичайно, "тест" - це логічно правильна функція, якщо ви шукаєте булевого результату. Дякуємо за Q / A BTW.
Девід Гілбертсон

2
Цікаво, що тест на 41% повільніше, ніж для мене, використовуючи тест jsPerf, описаний вище (Chrome 41, OSX).
Бенджі

1
@AlexShilman indexOf - це швидше (але не набагато), ніж тест відповідно до цього stackoverflow.com/questions/183496/… (ви б очікували, що це буде швидше).
підперсон

1
Одне, що може вас укусити тут (це нещодавно покусало мою команду): Якщо ви використовуєте прапор 'g' на своєму Regex і створюєте новий екземпляр (тобто через новий RegExp (<regex_str>, 'g')), і ви повторно використовуєте це Наприклад, запуск "test" є стаціонарним, тобто повертає різні результати при виконанні декількох разів. Докладні відомості див. У програмі developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
давертрон

118

Не забудьте взяти до уваги глобальний прапор у своєму regexp:

var reg = /abc/g;
!!'abcdefghi'.match(reg); // => true
!!'abcdefghi'.match(reg); // => true
reg.test('abcdefghi');    // => true
reg.test('abcdefghi');    // => false <=

Це тому, що Regexp відстежує lastIndex, коли буде знайдено новий збіг.


21
Я просто головою стукав, бачачи, що мій regex.test () випадково записував "true", потім "false", тоді "true" ... дякую!
adriendenat

7
Я думаю, що це краща відповідь. Це пояснює, що вони не дають однакового результату, і що reg.test () має небезпечну проблему. Для мене це робить string.match () чітким вибором. Виступ ніколи не був для мене жодним питанням.
Джеймс

2
Це важливо! Перехід з розуму , намагаючись зрозуміти, чому кожен другий результат не вистачає ... для довідки кого - або іншого , що знаходить це: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / ...
Dan

2
Якщо ви так само розгублені, як і я, дивіться stackoverflow.com/q/1520800/3714913 . Є також String.prototype.search () , який повертає індекс, але не має цієї проблеми, наскільки я можу сказати.
Nateowami

3
Просто цікаво, у чому сенс мати глобальний прапор .test()? Чи не сенс .test()перевіряти, чи є в рядку відповідне regexp?
buhbang

0

Це мої результати результати порівняння

тест 4,267,740 ops / sec ± 1,32% (60 проб проби)

exec 3,649,719 ops / sec ± 2,51% (60 проб вибірки)

матч 3,623,125 ops / sec ± 1,85% (62 проби вибірки)

індексO 6,230,325 ops / sec ± 0,95% (62 проби вибірки)

метод тестування швидший, ніж метод відповідності, але найшвидшим методом є indexOf


indexOf не працює з регулярними виразами настільки неактуально.
gdoron підтримує Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.