Ekspresi reguler untuk mencari Gadaffi


361

Saya mencoba mencari kata Gadaffi. Apa ekspresi reguler terbaik untuk mencari ini?

Upaya terbaik saya sejauh ini adalah:

\b[KG]h?add?af?fi$\b

Tapi sepertinya saya masih kehilangan beberapa jurnal. Ada saran?

Pembaruan: Saya menemukan daftar yang cukup luas di sini: http://blogs.abcnews.com/theworldnewser/2009/09/how-banyak-beda-selalu-dapat-anda-Anda-mantra-gaddafi.html

Jawaban di bawah cocok dengan semua 30 varian:

Gadaffi
Gadafi
Gadafy
Khadafi
Gaddafy
Khadafi
Gadhafi
Gathafi
Ghadaffi
Ghadafi
Ghaddafi
Ghaddafy
Gheddafi
Kadaffi
Kadafi
Khadafi
Kadhafi
Kazzafi
Khadaffy
Khadafy
Khaddafi
Qadafi
Qaddafi
Qadhafi
Qadhdhafi
Qadthafi
Qathafi
Quathafi
Qudhafi
Kad'afi

8
Yang mana yang Anda lewatkan? Dan di mana Anda mencari, apakah ada pencarian web dengan regex?
Czechnology

43
Selalu ada jurnal baru yang diterbitkan, jadi jika mereka terus menulis tentang Gadaffi Anda akan cenderung .+menjadi satu-satunya ungkapan reguler yang valid.
moinudin

30
Saya menemukan bahwa gambar ini membantu dengan ejaan yang berbeda: upload.wikimedia.org/math/6/1/f/...
KLee1

24
Seperti biasa, Lisp mengimplementasikan ini terlebih dahulu - foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp (gulir sekitar setengah jalan ke bawah)
Daniel S. Sterling

7
@Daniel Sterling: sebenarnya, tes Khadafy adalah bagian dari tes grep GNU sejak komitmen awal untuk RCS (Sel 3 Nov 21:38:52 1998 +0000), dan mungkin bahkan lebih tua dari itu!
Paolo Bonzini

Jawaban:


138

\b[KGQ]h?add?h?af?fi\b

Transkripsi bahasa Arab adalah (kata Wiki) "Qaḏḏāfī", jadi mungkin menambahkan Q. Dan satu H ("Gadhafi", seperti yang disebutkan dalam artikel (lihat di bawah)).

Btw, mengapa ada $di akhir regex?


Btw, artikel bagus tentang topik ini:

Gaddafi, Kadafi, atau Qaddafi? Mengapa nama pemimpin Libya dieja dengan berbagai cara? .


EDIT

Untuk mencocokkan semua nama dalam artikel yang Anda sebutkan nanti , ini harus cocok dengan semuanya. Semoga saja itu tidak cocok dengan banyak hal lain: D

\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b

$ Salah, saya lebih dulu mencocokkan ujung baris, lupa menghapusnya.
SiggyF

Apakah djuga cocok dengan ḏ?
SiggyF

2
@ DiggyF, tidak, saya hanya berpikir bahwa jika transkripsi arab mengatakan Qaḏḏāfī, regex harus memeriksa Qaddafijuga. Jika Anda ingin mencari transkripsi arab juga, cari saja yang - saya tidak berpikir ada lebih banyak varian transkripsi arab, hanya transkripsi bahasa inggris.
Czechnology

@DiggyF, saya telah mengedit dalam regex yang lebih panjang yang cocok dengan semua nama dalam artikel yang telah Anda posting (kecuali keduanya dengan ?alih - alih huruf). Mungkin butuh banyak usaha keras.
Czechnology

2
Ini juga cocok dengan 'Quuzzafi' dan sekelompok positif palsu lainnya, meskipun saya kira dalam mencari melalui laporan berita dll. Itu tidak masalah.
ben w

275

Mudah ... (Qadaffi|Khadafy|Qadafi|... )... didokumentasikan sendiri, dipelihara, dan dengan asumsi mesin regexp Anda benar-benar mengkompilasi ekspresi reguler (daripada menafsirkannya), itu akan dikompilasi ke DFA yang sama dengan solusi yang lebih dikaburkan.

Menulis ekspresi reguler yang ringkas seperti menggunakan nama variabel pendek untuk mempercepat program. Ini hanya membantu jika kompiler Anda mati otak.


23
Jawaban bagus! Orang-orang menggunakan ekspresi reguler jauh lebih sering daripada mereka peduli tentang bagaimana mereka sebenarnya bekerja.
Thomas Ahle

3
Saya sangat suka kesederhanaan dari solusi ini juga, tetapi saya terkejut bahwa ini akan dikompilasi ke DFA yang sama. Apakah Anda memiliki tautan yang membicarakan hal ini? Secara intuitif ini sepertinya kurang efisien daripada regex yang dibuat sebelumnya atau jawaban di bawah ini yang menyarankan menggunakan modul Regexp :: Assemble perl pada daftar nama or'd yang sama.
Rian Sanderson

6
-1 Inti dari suatu regex adalah untuk mengurangi apa yang seringkali - seperti dalam kasus ini - daftar alternatif yang sangat panjang untuk formula yang relatif pendek. Hasilnya sering dapat mengeksekusi lebih cepat daripada melakukan apa yang pada dasarnya adalah pencarian lengkap yang tidak dioptimalkan.
martineau

7
Anda benar, bahwa titik regex adalah untuk memberikan representasi yang ringkas dan jelas untuk sejumlah besar nilai. Tetapi konsep dasarnya adalah menghadirkan regex dan mengatakan "apa pun yang cocok dengan ini bagus." Artinya, Anda menganggap Anda memiliki kebebasan untuk memasukkan sesuatu yang sistematis. Di sini, kita memiliki situasi yang berlawanan: ejaan varian (dan variasi yang tidak pernah muncul) hanyalah sisi 'acak yang benar-benar'. Upaya rumit di "kompak" mendapatkan poin sangat rendah untuk "jelas"!
jackr

1
Lihat juga algoritma Aho-Corasick, yang optimal untuk pencarian string secara bersamaan: en.wikipedia.org/wiki/…
Thomas Ahle

45

Satu hal yang menarik untuk dicatat dari daftar ejaan potensial Anda adalah bahwa hanya ada 3 nilai Soundex untuk daftar yang terkandung (jika Anda mengabaikan 'Kazzafi' outlier)

G310, K310, Q310

Sekarang, ada positif palsu di sana ('Godby' juga adalah G310), tetapi dengan menggabungkan metafon hit terbatas juga, Anda dapat menghilangkannya.

<?
$soundexMatch = array('G310','K310','Q310');
$metaphoneMatch = array('KTF','KTHF','FTF','KHTF','K0F');

$text = "This is a big glob of text about Mr. Gaddafi. Even using compound-Khadafy terms in here, then we might find Mr Qudhafi to be matched fairly well. For example even with apostrophes sprinkled randomly like in Kad'afi, you won't find false positives matched like godfrey, or godby, or even kabbadi";

$wordArray = preg_split('/[\s,.;-]+/',$text);
foreach ($wordArray as $item){
    $rate = in_array(soundex($item),$soundexMatch) + in_array(metaphone($item),$metaphoneMatch);
    if ($rate > 1){
        $matches[] = $item;
    }
}
$pattern = implode("|",$matches);
$text = preg_replace("/($pattern)/","<b>$1</b>",$text);
echo $text;
?>

Beberapa perubahan, dan katakanlah beberapa transliterasi cyrillic, dan Anda akan memiliki solusi yang cukup kuat.


2
Harap dicatat, soundex khusus untuk Bahasa Inggris, ada ada algoritma fonetik lain untuk bahasa lain dengan aturan pengucapan yang berbeda
Incognito

8
Meskipun ini benar, kita berada dalam situasi yang aneh di sini. Permintaan utama adalah "Saya mencoba mencari kata Gadaffi", tetapi saya merasa regex adalah ikan haring merah. Tidak ada buku aturan pada transliterasi bahasa Arab-> latin, dan dengan demikian membatalkan regex dari daftar tidak akan sepenuhnya menjawab permintaan asli.
tomwalsham

2
Saya merasa sistem pencocokan fuzzy lebih cocok, tetapi algoritma khusus tampaknya berlebihan. Menggunakan kombo soundex-metaphone tampaknya berkinerja sebaik solusi regex, memungkinkan untuk ejaan lebih lanjut yang tidak diantisipasi sementara masih hanya menggunakan algo yang tidak tersedia.
tomwalsham

Penggunaan metaphone2 dan metaphone3 mengarah ke hasil yang lebih baik (yaitu, hampir semua yang ada di metaphone2 adalah KDF, sedangkan metaphone1 tidak cukup). Namun, Metaphone3 berharga sekitar 40 dolar.
Incognito

27

Menggunakan modul CPAN Regexp :: Assemble :

#!/usr/bin/env perl

use Regexp::Assemble;

my $ra = Regexp::Assemble->new;
$ra->add($_) for qw(Gadaffi Gadafi Gadafy Gaddafi Gaddafy
                    Gaddhafi Gadhafi Gathafi Ghadaffi Ghadafi
                    Ghaddafi Ghaddafy Gheddafi Kadaffi Kadafi
                    Kaddafi Kadhafi Kazzafi Khadaffy Khadafy
                    Khaddafi Qadafi Qaddafi Qadhafi Qadhdhafi
                    Qadthafi Qathafi Quathafi Qudhafi Kad'afi);
say $ra->re;

Ini menghasilkan ekspresi reguler berikut:

(?-xism:(?:G(?:a(?:d(?:d(?:af[iy]|hafi)|af(?:f?i|y)|hafi)|thafi)|h(?:ad(?:daf[iy]|af?fi)|eddafi))|K(?:a(?:d(?:['dh]a|af?)|zza)fi|had(?:af?fy|dafi))|Q(?:a(?:d(?:(?:(?:hd)?|t)h|d)?|th)|u(?:at|d)h)afi))

23

Saya pikir Anda terlalu rumit di sini. Regex yang benar adalah sesederhana:

\u0627\u0644\u0642\u0630\u0627\u0641\u064a

Ini cocok dengan rangkuman dari tujuh poin kode Unicode Arab yang membentuk kata القذافي (yaitu Gadaffi).


3
Selanjutnya, cukup sambungkan nytimes.com melalui Google Translate dan Bob, paman Anda.
Robert Rossney

19

Jika Anda ingin menghindari mencocokkan hal-hal yang tidak ada yang pernah digunakan (yaitu menghindari cenderung ke arah ". +") Pendekatan terbaik Anda adalah membuat ekspresi reguler yang hanya semua alternatif (mis. (Qadafi | Kadafi | ...) ) kemudian kompilasi itu menjadi DFA, dan kemudian ubah kembali DFA menjadi ekspresi reguler. Dengan asumsi implementasi yang cukup masuk akal yang akan memberi Anda ekspresi reguler "terkompresi" yang dijamin tidak mengandung varian yang tidak terduga.


2
Saya tahu hal itu mungkin terjadi, tetapi bagaimana Anda melakukannya dalam praktik (misalnya menggunakan bahasa dinamis yang umum)
Rory

3
Saya mengerti teori di balik ini, tetapi seperti @Rory, saya juga tertarik untuk mengetahui bagaimana Anda sebenarnya melakukan ini dalam praktik.
dancavallaro

ya, saya berpikir untuk melakukannya, untuk memberikan jawaban yang lebih baik, tetapi saya agak sibuk saat ini. saya punya beberapa (jelek dan kurang terdokumentasi) kode di code.google.com/p/lepl/source/browse/src/lepl/regexp/core.py yang membangun dfa dari regexp (sebenarnya, parser berada di kelas lain , tetapi kerja keras ada di sana; Anda pergi regexp -> nfa -> dfa). pergi dari dfa ke regexp itu mudah (saya pikir?).
andrew cooke

sebenarnya, dokumentasi di sana lebih baik daripada yang saya ingat: o) ide dasarnya adalah Anda menggambarkan regexp dalam hal kelas di dekat bagian atas file. yang kemudian dapat diterjemahkan ke nfa cukup mudah (nfa sebenarnya hanya serangkaian transisi yang mengatakan "jika Anda mendapatkan surat ini daripada Anda bisa pergi di sini atau di sini ..." itu cukup mudah dimengerti). dfa kemudian menjadi semacam versi "diperluas" di mana Anda terus menghindari keharusan mundur; itu dilakukan oleh NfaToDfa (dan merupakan bagian yang sulit). dfa kemudian dapat dianggap sebagai regexp itu sendiri yang ditulis sebagai set karakter yang sangat kompleks (?!)
andrew cooke

10

Jika Anda memiliki daftar yang konkrit dari 30 kemungkinan, cukup gabungkan semuanya bersama-sama dengan sekelompok "ors". Maka Anda dapat yakin bahwa itu hanya cocok dengan hal-hal persis yang telah Anda daftarkan, dan tidak lebih. Mesin RE Anda mungkin akan dapat dioptimalkan lebih lanjut, dan, yah, dengan 30 pilihan meskipun tidak, itu masih bukan masalah besar. Mencoba untuk bermain-main dengan secara manual mengubahnya menjadi "pintar" RE tidak mungkin menjadi lebih baik dan mungkin menjadi lebih buruk.


9
(G|Gh|K|Kh|Q|Qh|Q|Qu)(a|au|e|u)(dh|zz|th|d|dd)(dh|th|a|ha|)(\x27|)(a|)(ff|f)(i|y)

Tentu saja bukan versi yang paling optimal, berpisah pada suku kata untuk memaksimalkan kecocokan sambil berusaha memastikan kami tidak mendapatkan hasil positif yang salah.


7

Nah karena Anda mencocokkan kata-kata kecil mengapa Anda tidak mencoba mesin pencari kesamaan dengan jarak Levenshtein ? Anda dapat mengizinkan paling banyak k penyisipan atau penghapusan. Dengan cara ini Anda dapat mengubah fungsi jarak ke hal lain yang berfungsi lebih baik untuk masalah spesifik Anda. Ada banyak fungsi yang tersedia di perpustakaan simMetrics.



1

Mengapa tidak melakukan pendekatan campuran? Sesuatu antara daftar semua kemungkinan dan Regex yang rumit yang sangat cocok.

Regex adalah tentang pencocokan pola dan saya tidak dapat melihat pola untuk semua varian dalam daftar. Mencoba melakukannya, juga akan menemukan hal-hal seperti "Gazzafy" atau "Quud'haffi" yang kemungkinan besar bukan varian yang digunakan dan pasti tidak ada dalam daftar.

Tapi saya bisa melihat pola untuk beberapa varian, dan akhirnya saya menemukan ini:

\b(?:Gheddafi|Gathafi|Kazzafi|Kad'afi|Qadhdhafi|Qadthafi|Qudhafi|Qu?athafi|[KG]h?add?h?aff?[iy]|Qad[dh]?afi)\b

Pada awalnya saya daftar yang mana saya tidak bisa melihat pola, kemudian diikuti oleh beberapa varian di mana ada pola.

Lihat di sini di www.rubular.com


Anda \bhanya termasuk dalam alternatif pertama dan terakhir.
Christopher Creutzig

1

Saya tahu ini adalah pertanyaan lama, tapi ...

Tidak satu pun dari kedua regex ini yang tercantik, tetapi keduanya dioptimalkan dan keduanya SEMUA cocok dengan variasi dalam posting asli.

"Little Beauty" # 1

(?:G(?:a(?:d(?:d(?:af[iy]|hafi)|af(?:f?i|y)|hafi)|thafi)|h(?:ad(?:daf[iy]|af?fi)|eddafi))|K(?:a(?:d(?:['dh]a|af?)|zza)fi|had(?:af?fy|dafi))|Q(?:a(?:d(?:(?:(?:hd)?|t)h|d)?|th)|u(?:at|d)h)afi)

"Little Beauty" # 2

(?:(?:Gh|[GK])adaff|(?:(?:Gh|[GKQ])ad|(?:Ghe|(?:[GK]h|[GKQ])a)dd|(?:Gadd|(?:[GKQ]a|Q(?:adh|u))d|(?:Qad|(?:Qu|[GQ])a)t)h|Ka(?:zz|d'))af)i|(?:Khadaff|(?:(?:Kh|G)ad|Gh?add)af)y

Istirahat dalam Damai, Muammar.


0

Hanya sebuah tambahan: Anda harus menambahkan "Gheddafi" sebagai ejaan alternatif. Jadi RE seharusnya

\b[KG]h?[ae]dd?af?fi$\b

0

[GQK] [ahu] + [dtez] + \ '? [Adhz] + f {1,2} (i | y)

Di bagian:

  • [GQK]
  • [ahu] +
  • [dtez] +
  • \ '?
  • [adhz] +
  • f {1,2} (i | y)

Catatan: Hanya ingin mencoba ini.


-1

Apa lagi yang dimulai dengan Q, G, atau K, memiliki iklan, z atau t di tengah, dan berakhir dengan "fi" yang sebenarnya dicari orang?

/\b[GQK].+[dzt].+fi\b/i

Selesai

>>> print re.search(a, "Gadasadasfiasdas") != None
False
>>> print re.search(a, "Gadasadasfi") != None
True
>>> print re.search(a, "Qa'dafi") != None
True

Menarik bahwa saya mendapatkan suara turun. Dapatkah seseorang meninggalkan beberapa hal positif yang salah dalam komentar?


2
Dari kamus retak yang kebetulan aku telah duduk di sekitar: kartografi kryptografi Gaddafi Qaddafi gadafi gaddafi katastloofi katastorfi katastrofi khadaffi kadafi kardiyografi gaskromatografi kardiografi kinematografi kromatografi krystallografi kulturgeografi gandolfi grizzaffi gadhafi kadaffi kaddafi khaddafi qaddafi qadhafi quedaffi gordonsCHsKFI . Namun, beberapa di antaranya bukan positif palsu .
BMDan

2
Dan tambahan ke daftar itu yang dihasilkan dari berakhiran [iy]bukan hanya i:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.