regex.test VS string.match untuk mengetahui apakah suatu string cocok dengan ekspresi reguler

287

Sering kali saya menggunakan string match fungsi untuk mengetahui apakah string cocok dengan ekspresi reguler.

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

Apakah ada perbedaan antara ini:

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

Mereka sepertinya memberikan hasil yang sama?

gdoron mendukung Monica
sumber
4
ini adalah tes terbaik yang akan Anda temukan jsperf.com/regexp-test-vs-match-m5
ajax333221
@ ajax333221. Terima kasih atas jsperf, tapi saya tidak yakin itu bagus. Regex cocok menggunakan grup pertandingan, yang tidak diperlukan saat mencari nilai boolean.
gdoron mendukung Monica

Jawaban:

440

Penggunaan Dasar

Pertama, mari kita lihat apa fungsi masing-masing:

regexObject . tes ( String )

Menjalankan pencarian untuk kecocokan antara ekspresi reguler dan string yang ditentukan. Mengembalikan nilai true atau false .

tali . pertandingan ( RegExp )

Digunakan untuk mengambil kecocokan saat mencocokkan string dengan ekspresi reguler. Mengembalikan array dengan pertandingan atau nulljika tidak ada.

Sejak nulldievaluasi menjadi false,

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

Performa

Apakah ada perbedaan mengenai kinerja?

Ya . Saya menemukan catatan singkat ini di situs MDN :

Jika Anda perlu tahu apakah string cocok dengan ekspresi reguler regexp, gunakan regexp.test (string).

Apakah perbedaannya signifikan?

Jawabannya sekali lagi adalah YA ! JsPerf ini saya kumpulkan menunjukkan perbedaannya adalah ~ 30% - ~ 60% tergantung pada browser:

test vs match |  Uji kinerja

Kesimpulan

Gunakan .testjika Anda ingin pemeriksaan boolean yang lebih cepat. Gunakan .matchuntuk mengambil semua kecocokan saat menggunakan gbendera global.

gdoron mendukung Monica
sumber
5
Tidak terlalu terkejut karena fungsi string perlu membalikkan keadaan lalu membuat Array jika ada kecocokan. Sepertinya saya akan terus menggunakan .test(). :)
22
Dua sen saya: kinerja terlalu tinggi. Pilihan mana pun dapat melakukan ~ 15.000 operasi dalam sekejap monitor, jadi kecuali Anda melakukan sisi klien sisi regex, kecepatan tidak relevan. Tentu saja 'tes' adalah fungsi yang benar jika hasil boolean adalah apa yang Anda cari. Terima kasih atas Q / A BTW.
David Gilbertson
2
Tes yang menarik 41% lebih lambat daripada yang cocok untuk saya menggunakan tes jsPerf di atas (Chrome 41, OSX).
Benjie
1
@AlexShilman indexOf lebih cepat (tapi tidak banyak) daripada pengujian menurut stackoverflow.com/questions/183496/… ini (Anda harapkan lebih cepat).
podperson
1
Satu hal yang mungkin menggigit Anda di sini (itu menggigit tim saya baru-baru ini): Jika Anda menggunakan bendera 'g' di Regex Anda dan membuat contoh baru (yaitu melalui RegExp baru (<regex_str>, 'g')) dan Anda menggunakan kembali itu Misalnya, menjalankan "tes" adalah stateful, yaitu akan mengembalikan hasil yang berbeda ketika dijalankan beberapa kali. Lihat developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… untuk detailnya.
davertron
118

Jangan lupa mempertimbangkan bendera global di regexp Anda:

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

Ini karena Regexp melacak LastIndex ketika kecocokan baru ditemukan.

gtournie
sumber
21
Saya baru saja membenturkan kepala melihat bahwa regex.test saya () secara acak login "benar" lalu "salah" lalu "benar" ... terima kasih!
adriendenat
7
Saya pikir ini adalah jawaban yang lebih baik. Ini menjelaskan bahwa mereka tidak memberikan hasil yang sama dan bahwa reg.test () memiliki jebakan berbahaya. Bagi saya ini membuat string.match () pilihan yang jelas. Kinerja tidak pernah menjadi masalah bagi saya.
James
2
Ini penting! Gila mencoba mencari tahu mengapa setiap hasil lainnya hilang ... untuk referensi orang lain yang menemukan ini: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dan
2
Jika Anda sama bingungnya dengan saya, lihat stackoverflow.com/q/1520800/3714913 . Ada juga String.prototype.search () , yang mengembalikan indeks tetapi tidak memiliki masalah ini sejauh yang saya tahu.
Nateowami
3
Hanya ingin tahu, untuk apa memiliki bendera global .test()? bukan gunanya .test()memeriksa apakah string memiliki regexp yang cocok?
buhbang
0

Ini adalah hasil benchmark saya hasil benchmark

uji 4.267.740 ops / dt ± 1.32% (60 run sampel)

exec 3.649.719 ops / dt ± 2.51% (60 run sampel)

cocok 3,623,125 ops / detik ± 1,85% (sampel 62 run)

indexOf 6.230.325 ops / dt ± 0.95% (62 run sampel)

Metode pengujian lebih cepat daripada metode pertandingan, tetapi metode tercepat adalah indexOf

Ramil Shavaleev
sumber
indexOf tidak bekerja dengan regex jadi sangat tidak relevan.
gdoron mendukung Monica