Pertanyaan Ekspresi reguler untuk menemukan dua string di mana saja dalam masukan


Bagaimana cara menulis ekspresi reguler untuk mencocokkan dua string yang diberikan, pada posisi apa pun dalam string?

Misalnya, jika saya mencari cat dan mat, itu harus cocok:

The cat slept on the mat in front of the fire.
At 5:00 pm, I found the cat scratching the wool off the mat.

Tidak peduli apa yang mendahului string ini.


36
2018-02-08 05:50


asal


Jawaban:


/^.*?\bcat\b.*?\bmat\b.*?$/m

Menggunakan m modifier (yang memastikan kecocokan metakarakter awal / akhir pada jeda baris daripada di awal dan akhir string):

  • ^ cocok dengan garis awal
  • .*? cocok dengan apa pun yang ada di garis sebelumnya ...
  • \b cocok dengan batas kata pertama kemunculan batas kata (sebagai @codaddict dibahas)
  • lalu string cat dan batas kata lain; perhatikan bahwa garis bawah diperlakukan sebagai karakter "kata", jadi _cat_ akan tidak pertandingan*;
  • .*?: setiap karakter sebelumnya ...
  • batas, mat, batas
  • .*?: karakter yang tersisa sebelum ...
  • $: akhir baris.

Sangat penting untuk digunakan \b untuk memastikan kata-kata yang ditentukan bukan bagian dari kata-kata yang lebih panjang, dan penting untuk menggunakan wildcard yang tidak rakus (.*?) versus serakah (.*) karena yang terakhir akan gagal pada string seperti "Ada kucing di atas tikar yang ada di bawah kucing." (Ini akan cocok dengan kejadian terakhir "kucing" daripada yang pertama.)

* Jika Anda ingin dapat mencocokkan _cat_, Kamu dapat memakai:

/^.*?(?:\b|_)cat(?:\b|_).*?(?:\b|_)mat(?:\b|_).*?$/m

yang cocok dengan garis bawah atau batas kata di sekitar kata-kata yang ditentukan. (?:) menunjukkan grup yang tidak menangkap, yang dapat membantu kinerja atau menghindari tangkapan yang bertentangan.

Edit: Sebuah pertanyaan muncul di komentar tentang apakah solusi akan berfungsi untuk frasa bukan hanya kata-kata. Jawabannya adalah, tentu saja ya. Berikut ini akan cocok dengan "Garis A yang mencakup frasa pertama dan frasa kedua":

/^.*?(?:\b|_)first phrase here(?:\b|_).*?(?:\b|_)second phrase here(?:\b|_).*?$/m

Edit 2: Jika pesanan tidak masalah Anda dapat menggunakan:

/^.*?(?:\b|_)(first(?:\b|_).*?(?:\b|_)second|second(?:\b|_).*?(?:\b|_)first)(?:\b|_).*?$/m

Dan jika kinerja benar-benar menjadi masalah di sini, mungkin mencari solusi (jika mesin regex Anda mendukungnya) mungkin (tetapi mungkin tidak akan) berkinerja lebih baik daripada yang di atas, tetapi saya akan meninggalkan kedua versi yang terlihat lebih kompleks dan pengujian kinerja sebagai latihan untuk penanya / pembaca.

Diedit per komentar @Alan Moore. Saya tidak memiliki kesempatan untuk mengujinya, tapi saya akan mengambil kata Anda untuk itu.


54
2018-02-08 07:15



(.* word1.* word2.* )|(.* word2.* word1.*)

15
2018-02-08 05:58



Anda dapat mencoba:

\bcat\b.*\bmat\b

\b adalah jangkar dan cocok dengan batas kata. Itu akan mencari kata-kata kucing dan tikar di mana saja di string dengan tikar kucing berikut. Ini tidak akan cocok:

Therez caterpillar on the mat.

tapi akan cocok

The cat slept on the mat in front of the fire

Jika Anda ingin mencocokkan string yang ada surat-surat kucing diikuti dengan tikar, Anda dapat mencoba:

cat.*mat

Ini akan cocok dengan kedua contoh di atas.


3
2018-02-08 05:52



Jika Anda benar-benar hanya perlu menggunakan satu regex lalu

/(?=.*?(string1))(?=.*?(string2))/is

i modifier = case-insensitive

. *? Evaluasi malas untuk karakter apa pun (sesuaikan sesering mungkin)

? = for Positive LookAhead itu harus cocok di suatu tempat

s modifier =. (periode) juga menerima jeda baris


3
2017-08-14 17:05



Ini cukup mudah untuk memproses daya yang diperlukan:

(string1(.|\n)*string2)|(string2(.|\n)*string1)

Saya menggunakan ini di studio visual 2013 untuk menemukan semua file yang memiliki string 1 dan 2 di dalamnya.


2
2017-11-18 22:52



Anda tidak harus menggunakan regex. Dalam bahasa favorit Anda, split pada spasi, pergi ke kata-kata terpisah, periksa kucing dan matras. misalnya dengan Python

>>> for line in open("file"):
...     g=0;f=0
...     s = line.split()
...     for item in s:
...         if item =="cat": f=1
...         if item =="mat": g=1
...     if (g,f)==(1,1): print "found: " ,line.rstrip()

found:  The cat slept on the mat in front of the fire.
found:  At 5:00 pm, I found the cat scratching the wool off the mat.

1
2018-02-08 06:33



Ini berfungsi untuk mencari file yang berisi String1 dan String2

(((. | \ n)) String1 ((. | \ N)) String2) | (((. | \ N)) String2 ((. | \ N)) String1)

Cocokkan sejumlah karakter atau bidang baris diikuti oleh String1 diikuti oleh sejumlah karakter atau bidang baris diikuti oleh String2 ATAU Cocokkan sejumlah karakter atau bidang baris diikuti oleh String2 diikuti oleh sejumlah karakter atau bidang baris diikuti oleh String1


0
2017-08-18 22:36