นิพจน์ทั่วไปเพื่อค้นหา Gadaffi


361

ฉันพยายามค้นหาคำว่า Gadaffi นิพจน์ทั่วไปที่ดีที่สุดในการค้นหาสิ่งนี้คืออะไร

ความพยายามที่ดีที่สุดของฉันคือ:

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

แต่ฉันก็ยังดูเหมือนจะหายไปบางวารสาร ข้อเสนอแนะใด ๆ

อัปเดต: ฉันพบรายการสวย ๆ ที่นี่: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

คำตอบด้านล่างตรงกับ 30 รูปแบบทั้งหมด:

Gadaffi
Gadafi
Gadafy
กัดดาฟี
Gaddafy
Gaddhafi
Gadhafi
Gathafi
Ghadaffi
Ghadafi
Ghaddafi
Ghaddafy
Gheddafi
Kadaffi
คาดาฟิ
Kaddafi
Kadhafi
Kazzafi
Khadaffy
Khadafy
Khaddafi
Qadafi
Qaddafi
กัดฮาฟิ
Qadhdhafi
Qadthafi
Qathafi
Quathafi
Qudhafi
Kad'afi

8
คุณหายไปไหน และคุณกำลังค้นหาอยู่ที่ไหนมีการค้นหาเว็บด้วย regex หรือไม่
Czechnology

43
มีวารสารใหม่ที่ตีพิมพ์อยู่เสมอดังนั้นหากพวกเขาเขียนเกี่ยวกับ Gadaffi คุณจะมีแนวโน้มที่จะ.+เป็นนิพจน์ปกติที่ถูกต้องเท่านั้น
moinudin

30
ฉันพบว่ารูปภาพนี้ช่วยในการสะกดคำต่าง ๆ : upload.wikimedia.org/math/6/1/f/…
KLee1

24
ตามปกติ Lisp ใช้งานครั้งแรก - foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp (เลื่อนประมาณครึ่งทาง)
Daniel S. Sterling

7
@Daniel Sterling: จริง ๆ แล้วการทดสอบ Khadafy เป็นส่วนหนึ่งของ GNU grep testsuite ตั้งแต่เริ่มต้นส่งมอบให้กับ RCS (อังคาร 3 พ.ย. 21:38:52 1998 +0000) และอาจแก่กว่านั้น!
เปาโลบอนซินี

คำตอบ:


138

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

การถอดความภาษาอาหรับคือ (Wiki พูดว่า) "Qaḏḏāfī" ดังนั้นอาจเพิ่ม Q และหนึ่ง H ("Gadhafi" เป็นบทความ (ดูด้านล่าง) กล่าวถึง)

แต่ทำไม$ตอนจบของ regex ถึงมีบ้าง?


Btw บทความที่ดีในหัวข้อ:

Gaddafi, Kadafi หรือ Qaddafi? เหตุใดผู้นำของลิเบียจึงสะกดหลายวิธี? .


แก้ไข

เพื่อให้ตรงกับชื่อทั้งหมดในบทความที่คุณพูดถึงในภายหลังสิ่งนี้ควรตรงกับชื่อทั้งหมด หวังว่ามันจะไม่ตรงกับสิ่งอื่น ๆ อีกมากมาย: D

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

$ ผิดฉันจับคู่จุดจบก่อนลืมลบออก
SiggyF

ไม่dตรงกับ D หรือไม่?
SiggyF

2
@DiggyF ไม่ฉันแค่คิดว่าถ้าการถอดความภาษาอาหรับพูดว่าQaḏḏāfīregex ควรตรวจสอบQaddafiด้วย หากคุณต้องการค้นหาการถอดความภาษาอาหรับด้วยให้ค้นหาคำนั้น - ฉันไม่คิดว่าจะมีการถอดความภาษาอาหรับอีกมาก
Czechnology

@DiggyF ฉันได้แก้ไขใน regex ที่ยาวขึ้นซึ่งตรงกับชื่อทั้งหมดในบทความที่คุณโพสต์ (ยกเว้นทั้งสองด้วย?แทนที่จะเป็นตัวอักษร) อาจเป็น overkill แม้ว่า
Czechnology

2
สิ่งนี้ยังตรงกับ 'Quuzzafi' และผลบวกเท็จอื่น ๆ อีกมากมายแม้ว่าฉันคิดว่าในการค้นหาผ่านรายงานข่าว ฯลฯ ที่ไม่สำคัญมาก
เบน W

275

ง่าย ... (Qadaffi|Khadafy|Qadafi|... )... เป็นเอกสารที่จัดทำเองบำรุงรักษาและสมมติว่าเครื่องมือ regexp ของคุณรวบรวมการแสดงออกปกติ (แทนที่จะแปลพวกเขา) จริง ๆ แล้วมันจะรวบรวม DFA เดียวกันกับที่โซลูชันที่ยุ่งยากกว่าจะทำ

การเขียนนิพจน์ทั่วไปที่มีขนาดกะทัดรัดนั้นเหมือนกับการใช้ชื่อตัวแปรสั้น ๆ เพื่อเร่งความเร็วโปรแกรม มันจะช่วยได้ก็ต่อเมื่อคอมไพเลอร์ของคุณสมองตาย


23
คำตอบที่ดี! ผู้คนใช้การแสดงออกปกติบ่อยกว่าที่พวกเขาสนใจเกี่ยวกับวิธีการใช้งานจริง
โทมัส Ahle

3
ฉันชอบความเรียบง่ายของโซลูชันนี้เช่นกัน แต่ฉันประหลาดใจที่สิ่งนี้จะรวบรวมลงใน DFA เดียวกัน คุณมีลิงค์ที่พูดถึงเรื่องนี้หรือไม่? ดูเหมือนว่ามันจะมีประสิทธิภาพน้อยกว่า regex ที่สร้างขึ้นก่อนหน้านี้หรือคำตอบด้านล่างซึ่งแนะนำให้ใช้โมดูล Regexp :: Assemble perl ในรายการชื่อหรือชื่อเดียวกัน
Rian Sanderson

6
-1 จุดทั้งหมดของ regex คือการลดสิ่งที่มักจะเป็น - ในกรณีนี้ - รายการทางเลือกที่ยาวมาก ๆ สำหรับสูตรที่ค่อนข้างสั้น ผลลัพธ์มักจะสามารถทำงานได้เร็วกว่าการทำในสิ่งที่เป็นการค้นหาแบบหมดจด
martineau

7
คุณพูดถูกจุด regexes คือการให้การแสดงที่กะทัดรัดและชัดเจนสำหรับชุดของค่าขนาดใหญ่ แต่แนวคิดพื้นฐานคือการนำเสนอ regex และพูดว่า "อะไรก็ตามที่ตรงกับสิ่งนี้ถือว่าดี" นั่นคือถือว่าคุณมีอิสระที่จะรวมสิ่งใด ๆ ที่เป็นระบบไว้ ที่นี่เรามีสถานการณ์ตรงกันข้าม: การสะกดคำที่แตกต่างกัน (และรูปแบบที่ไม่เคยปรากฏ) เป็นเพียงด้านนี้ของ 'สุ่มเต็ม' ความพยายามที่ซับซ้อนที่ "กะทัดรัด" ได้รับคะแนนต่ำมากสำหรับ "ชัดเจน"!
jackr

1
นอกจากนี้ลองดูอัลกอริทึม Aho-Corasick ซึ่งเหมาะสำหรับการค้นหาสตริงพร้อมกัน: en.wikipedia.org/wiki/ …
Thomas Ahle

45

สิ่งหนึ่งที่น่าสนใจที่จะทราบจากรายการการสะกดที่อาจเกิดขึ้นของคุณคือมีค่า Soundex เพียง 3 ค่าสำหรับรายการที่มีอยู่ (หากคุณไม่สนใจ 'Kazzafi' ที่เกินค่า)

G310, K310, Q310

ตอนนี้มีผลบวกปลอมอยู่ในนั้น ('Godby' ก็คือ G310) แต่เมื่อรวม metaphone ที่มีจำนวน จำกัด เข้าด้วยกันคุณสามารถกำจัดมันได้

<?
$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;
?>

การปรับแต่งเล็กน้อยและให้พูดการทับศัพท์ภาษาไซริลบางตัวและคุณจะมีวิธีแก้ปัญหาที่ค่อนข้างแข็งแกร่ง


2
โปรดทราบว่า soundex มีความเชี่ยวชาญในภาษาอังกฤษมีอัลกอริทึมการออกเสียงอื่น ๆ สำหรับภาษาอื่นที่มีกฎการออกเสียงแตกต่างกัน
Incognito

8
ในขณะนี้เป็นจริงเราอยู่ในสถานการณ์แปลก ๆ ที่นี่ คำขอหลักคือ "ฉันพยายามค้นหาคำว่า Gadaffi" แต่ฉันรู้สึกว่า regex เป็นปลาเฮอริ่งแดง ไม่มีกฎเกี่ยวกับการทับศัพท์ภาษาอาหรับ - ภาษาละตินและการย้อนกลับ regex จากรายการจะไม่ตอบคำขอต้นฉบับทั้งหมด
tomwalsham

2
ฉันรู้สึกว่าระบบจับคู่แบบคลุมเครือนั้นเหมาะสมกว่า แต่อัลกอริทึมที่กำหนดเองดูเหมือนจะเกินความจริง การใช้คำสั่งผสม soundex-metaphone ดูเหมือนว่าจะทำงานได้ดีเช่นเดียวกับโซลูชัน regex ทำให้สามารถทำการสะกดคำที่ไม่คาดคิดในขณะที่ยังใช้ algos แบบนอกชั้นวางได้
tomwalsham

การใช้ metaphone2 และ metaphone3 นำไปสู่ผลลัพธ์ที่ดีกว่า (กล่าวคือเกือบทุกอย่างใน metaphone2 คือ KDF โดยที่ metaphone1 นั้นไม่ได้เป็นอย่างนั้น) อย่างไรก็ตาม Metaphone3 มีราคาประมาณ 40 bucks
ไม่ระบุตัวตน

27

ใช้โมดูล 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;

สิ่งนี้สร้างนิพจน์ทั่วไปต่อไปนี้:

(?-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

ฉันคิดว่าคุณกำลังยุ่งอยู่กับสิ่งต่าง ๆ ที่นี่ regex ที่ถูกต้องนั้นง่ายพอ ๆ กับ:

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

มันตรงกับการต่อกันของเจ็ดโค้ดอารบิก Unicode ที่เป็นคำว่าالقذافي (เช่น Gadaffi)


3
ถัดไปเพียงแค่ไพพ์ nytimes.com ผ่าน Google Translate และ Bob เป็นลุงของคุณ
Robert Rossney

19

หากคุณต้องการหลีกเลี่ยงการจับคู่สิ่งต่าง ๆ ที่ไม่มีใครใช้ (เช่นหลีกเลี่ยงการพุ่งเข้าหา ". +") วิธีที่ดีที่สุดของคุณคือการสร้างการแสดงออกปกตินั่นเป็นเพียงทางเลือกทั้งหมด (เช่น (Qadafi | Kadafi | ... ) ) จากนั้นรวบรวมว่าเป็น DFA แล้วแปลง DFA กลับไปเป็นนิพจน์ทั่วไป สมมติว่ามีการใช้งานที่สมเหตุสมผลพอสมควรซึ่งจะให้นิพจน์ทั่วไป "ที่ถูกบีบอัด" ซึ่งรับประกันได้ว่าจะไม่มีตัวแปรที่ไม่คาดคิด


2
ฉันรู้ว่ามันเป็นไปได้ในทางทฤษฎี แต่คุณจะทำอย่างไรในทางปฏิบัติ (โดยใช้ภาษาแบบไดนามิกทั่วไปเช่น som)
384 Rory

3
ฉันเข้าใจทฤษฎีที่อยู่เบื้องหลังสิ่งนี้ แต่เช่น @Rory ฉันสนใจที่จะรู้ว่าคุณจะทำสิ่งนี้อย่างไรในทางปฏิบัติ
dancavallaro

ใช่ฉันคิดเกี่ยวกับการทำมันเพื่อให้คำตอบที่ดีขึ้น แต่ฉันไม่ว่างในขณะนี้ ฉันมีรหัสบางอย่าง (น่าเกลียดและไม่ดี) ที่code.google.com/p/lepl/source/browse/src/lepl/regexp/core.pyที่สร้าง dfa จาก regexp (จริงๆแล้ว parser อยู่ในคลาสอื่น แต่การทำงานหนักอยู่ที่นั่นคุณไป regexp -> nfa -> dfa) การเปลี่ยนจาก dfa เป็น regexp นั้นง่าย (ฉันคิดว่า?)
andrew cooke

ที่จริงแล้วเอกสารมีดีกว่าที่ฉันจำได้: o) แนวคิดพื้นฐานคือคุณอธิบาย regexp ในแง่ของการเรียนใกล้ด้านบนของไฟล์ จากนั้นสามารถแปลเป็น nfa ได้ง่าย ๆ (nfa เป็นเพียงชุดของการเปลี่ยนคำพูดที่ว่า "ถ้าคุณได้รับจดหมายฉบับนี้มากกว่าที่คุณสามารถไปที่นี่หรือที่นี่ ... " นั่นเป็นเรื่องที่เข้าใจได้ง่าย) dfa นั้นเป็นรุ่น "ขยาย" ที่คุณหลีกเลี่ยงที่จะย้อนกลับ ทำโดย NfaToDfa (และเป็นส่วนที่ยาก) dfa นั้นสามารถเป็น regexp ของตัวเองที่เขียนเป็นชุดอักขระที่ซับซ้อนมาก (?!)
andrew cooke

10

หากคุณมีรายการที่เป็นไปได้ทั้งหมด 30 รายการเพียงแค่เชื่อมต่อพวกเขาทั้งหมดเข้าด้วยกันด้วย "ors" จากนั้นคุณสามารถมั่นใจได้ว่ามันตรงกับสิ่งที่คุณระบุไว้เท่านั้นและไม่มาก เอ็นจิ้น RE ของคุณอาจจะสามารถเพิ่มประสิทธิภาพได้มากขึ้นและดีขึ้นโดยมี 30 ตัวเลือกแม้ว่าจะไม่เป็นเช่นนั้นก็ยังไม่ใช่เรื่องใหญ่ การพยายามทำตัวกลมกลืนด้วยการเปลี่ยนมันให้เป็น "ฉลาด" RE ไม่สามารถกลายเป็นดีกว่าและอาจแย่ลง


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)

แน่นอนว่าไม่ใช่รุ่นที่ได้รับการปรับปรุงมากที่สุดแบ่งเป็นพยางค์เพื่อเพิ่มการแข่งขันในขณะที่พยายามทำให้แน่ใจว่าเราจะไม่ได้รับผลบวกปลอม


7

ถ้าคุณจับคู่คำเล็ก ๆ ทำไมคุณไม่ลองใช้เครื่องมือค้นหาความคล้ายคลึงกันกับระยะทางของLevenshtein คุณสามารถอนุญาตการแทรกหรือลบได้สูงสุดk วิธีนี้คุณสามารถเปลี่ยนฟังก์ชันระยะทางเป็นสิ่งอื่นที่ทำงานได้ดีกว่าสำหรับปัญหาเฉพาะของคุณ มีฟังก์ชันมากมายที่มีอยู่ในไลบรารี simMetrics


4

ทางเลือกที่เป็นไปได้คือเครื่องมือออนไลน์สำหรับการสร้างการแสดงออกปกติจากตัวอย่างhttp://regex.inginf.units.it ให้โอกาส!


1

ทำไมไม่ทำแบบผสมผสาน? บางสิ่งระหว่างรายการของความเป็นไปได้ทั้งหมดและ Regex ที่ซับซ้อนซึ่งจับคู่กันมากเกินไป

Regex เป็นเรื่องเกี่ยวกับการจับคู่รูปแบบและฉันไม่เห็นรูปแบบสำหรับตัวแปรทั้งหมดในรายการ พยายามทำเช่นนั้นจะพบสิ่งต่าง ๆ เช่น "Gazzafy" หรือ "Quud'haffi" ซึ่งส่วนใหญ่อาจไม่ใช่ตัวแปรที่ใช้แล้วและไม่อยู่ในรายการ

แต่ฉันสามารถเห็นรูปแบบของตัวแปรต่างๆได้ดังนั้นฉันจึงจบลงด้วยสิ่งนี้:

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

ในตอนแรกฉันแสดงรายการที่ฉันไม่สามารถเห็นรูปแบบแล้วตามด้วยตัวแปรบางอย่างที่มีรูปแบบ

ดูได้ที่นี่บนwww.rubular.com


ของคุณ\bจะรวมอยู่ในทางเลือกแรกและสุดท้ายเท่านั้น
Christopher Creutzig

1

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ ...

ไม่ใช่ทั้งสอง regexes ที่สวยที่สุด แต่ได้รับการปรับให้เหมาะสมและทั้งคู่ต่างกันในรูปแบบทั้งหมดในโพสต์ต้นฉบับ

"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

พักผ่อนอย่างมีความสุข Muammar


0

เพียงแค่ภาคผนวก: คุณควรเพิ่ม "Gheddafi" เป็นตัวสะกดแบบอื่น ดังนั้น RE ควรจะเป็น

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

0

[GQK] [AHU] + [dtez] + \ '[adhz] + F {1,2} (i | y)?

ในส่วน:

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

บันทึก:แค่อยากให้ช็อตนี้


-1

มีอะไรอีกที่เริ่มต้นด้วย Q, G หรือ K, มีโฆษณา, z หรือ t อยู่ตรงกลาง, และลงท้ายด้วย "fi" ที่ผู้คนค้นหาจริง ๆ ?

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

เสร็จสิ้น

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

น่าสนใจที่ฉันลงคะแนน บางคนสามารถแสดงความคิดเห็นที่เป็นเท็จในความคิดเห็นได้หรือไม่?


2
จากพจนานุกรมที่แคร็กที่ฉันนั่งอยู่รอบ ๆ : 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 . บางคนไม่ได้เป็นเท็จบวกแม้ว่า
BMDan

2
และส่วนเพิ่มเติมของรายการนั้นเป็นผลมาจากการสิ้นสุดใน[iy]แทนที่จะเป็นเพียงi:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.