Regulärer Ausdruck zur Suche nach Gadaffi

361

Ich versuche nach dem Wort Gadaffi zu suchen. Was ist der beste reguläre Ausdruck, um danach zu suchen?

Mein bisher bester Versuch ist:

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

Aber ich vermisse immer noch einige Zeitschriften. Irgendwelche Vorschläge?

Update: Ich habe hier eine ziemlich umfangreiche Liste gefunden: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

Die Antwort unten entspricht allen 30 Varianten:

Gadaffi
Gadafi
Gadafy
Gaddafi
Gaddafy
Gaddafi
Gaddafi
Gathafi
Ghadaffi
Ghadafi
Ghaddafi
Ghaddafy
Gheddafi
Kadaffi
Kadafi
Kaddafi
Kadhafi
Kazzafi
Khadaffy
Khadafy
Khaddafi
Gaddafi
Gaddafi
Gaddafi
Gaddafi
Qadthafi
Qathafi
Quathafi
Qudhafi
Kad'afi
SiggyF
quelle
8
Welche vermisst du? Und wo suchen Sie, gibt es eine Websuche mit Regex?
Czechnology
43
Es werden immer neue Zeitschriften veröffentlicht. Wenn sie also weiter über Gadaffi schreiben, sind Sie in der Regel .+der einzig gültige reguläre Ausdruck.
Moinudin
30
Ich fand, dass dieses Bild mit den verschiedenen Schreibweisen hilft: upload.wikimedia.org/math/6/1/f/…
KLee1
24
Wie üblich implementierte Lisp dies zuerst - foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp (etwa auf halber Strecke nach unten scrollen)
Daniel S. Sterling
7
@ Daniel Sterling: Tatsächlich ist der Khadafy-Test seit dem ersten Commit für RCS (Di 3. November 21:38:52 1998 +0000) Teil der GNU-Grep-Testsuite und wahrscheinlich sogar noch älter!
Paolo Bonzini

Antworten:

138

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

Die arabische Transkription ist (Wiki sagt) "Qaḏḏāfī", also vielleicht ein Q. und ein H ("Gaddafi", wie im Artikel (siehe unten) erwähnt).

Übrigens, warum steht $am Ende des regulären Ausdrucks ein?


Übrigens, schöner Artikel zum Thema:

Gaddafi, Kadafi oder Gaddafi? Warum wird der Name des libyschen Führers so unterschiedlich geschrieben? .


BEARBEITEN

Damit alle Namen in dem Artikel, den Sie später erwähnt haben , übereinstimmen, sollte dies mit allen übereinstimmen. Hoffen wir nur, dass es nicht zu vielen anderen Dingen passt: D.

\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b
Tschechologie
quelle
Das $ ist falsch, ich habe zuerst das Zeilenende abgeglichen und vergessen, es zu entfernen.
SiggyF
Passt dauch ein ḏ?
SiggyF
2
@ DiggyF, nein, ich dachte nur, wenn die arabische Transkription sagt Qaḏḏāfī, sollte der Regex auch prüfen Qaddafi. Wenn Sie auch nach der arabischen Transkription suchen möchten, suchen Sie einfach nach dieser - ich glaube nicht, dass es mehr Varianten der arabischen Transkription gibt, nur der englischen Transkriptionen.
Czechnology
@DiggyF, ich habe eine längere Regex bearbeitet, die allen Namen in dem Artikel entspricht, den Sie gepostet haben (außer den beiden mit ?anstelle von Buchstaben). Könnte aber ein Overkill sein.
Czechnology
2
Dies passt auch zu 'Quuzzafi' und einer Reihe anderer falsch positiver Ergebnisse, obwohl ich vermute, dass dies beim Durchsuchen von Nachrichtenberichten usw. nicht viel ausmacht.
Ben w
275

Einfach ... (Qadaffi|Khadafy|Qadafi|... )... es ist selbstdokumentiert, wartbar und unter der Annahme, dass Ihre Regexp-Engine tatsächlich reguläre Ausdrücke kompiliert (anstatt sie zu interpretieren), wird sie mit demselben DFA kompiliert wie eine verschleiertere Lösung.

Das Schreiben kompakter regulärer Ausdrücke entspricht der Verwendung kurzer Variablennamen, um ein Programm zu beschleunigen. Es hilft nur, wenn Ihr Compiler hirntot ist.

Chris Pacejo
quelle
23
Gute Antwort! Menschen verwenden reguläre Ausdrücke weitaus häufiger, als es ihnen wichtig ist, wie sie tatsächlich arbeiten.
Thomas Ahle
3
Ich mag die Einfachheit dieser Lösung auch sehr, aber ich bin überrascht, dass dies bis zum gleichen DFA kompiliert wird. Haben Sie einen Link, der darüber spricht? Intuitiv scheint dies weniger effizient zu sein als der zuvor erstellte Regex oder die Antwort unten, die die Verwendung des Perl-Moduls Regexp :: Assemble für dieselbe Liste von Or'd-Namen vorschlägt.
Rian Sanderson
6
-1 Der springende Punkt einer Regex ist es, das zu reduzieren, was - wie in diesem Fall - oft eine sehr lange Liste von Alternativen zu relativ kurzen Formeln sein kann. Das Ergebnis kann oft schneller ausgeführt werden als eine im Wesentlichen nicht optimierte umfassende Suche.
Martineau
7
Sie haben Recht, dass der Sinn von Regexen darin besteht, eine kompakte, klare Darstellung für eine große Anzahl von Werten bereitzustellen. Aber das Grundkonzept besteht darin, einen regulären Ausdruck zu präsentieren und zu sagen: "Alles, was dazu passt, ist gut." Das heißt, es wird davon ausgegangen, dass Sie die Freiheit haben, systematische Elemente einzubeziehen. Hier haben wir die gegenteilige Situation: Die varianten Schreibweisen (und die Variationen, die niemals auftreten) sind kaum diese Seite von "absolut zufällig". Die aufwändigen Versuche "kompakt" bekommen sehr niedrige Punkte für "klar"!
Jackr
1
Schauen Sie sich auch den Aho-Corasick-Algorithmus an, der für die gleichzeitige Suche nach Zeichenfolgen optimal ist: en.wikipedia.org/wiki/…
Thomas Ahle
45

Eine interessante Sache aus Ihrer Liste möglicher Schreibweisen ist, dass es nur 3 Soundex-Werte für die enthaltene Liste gibt (wenn Sie den Ausreißer 'Kazzafi' ignorieren).

G310, K310, Q310

Jetzt gibt es dort falsch positive Ergebnisse ('Godby' ist auch G310), aber wenn Sie auch die begrenzten Metaphontreffer kombinieren, können Sie sie eliminieren.

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

Ein paar Änderungen und beispielsweise eine kyrillische Transliteration, und Sie haben eine ziemlich robuste Lösung.

Tomwalsham
quelle
2
Bitte beachten Sie, dass soundex auf Englisch spezialisiert ist. Es gibt andere phonetische Algorithmen für andere Sprachen mit anderen Ausspracheregeln
Incognito
8
Während dies wahr ist, befinden wir uns hier in einer merkwürdigen Situation. Die Hauptanfrage war "Ich versuche nach dem Wort Gadaffi zu suchen", aber ich glaube, der reguläre Ausdruck war ein roter Hering. Es gibt kein Regelwerk für Arabisch-> Latein-Transliteration, und daher wird das Umkehren eines regulären Ausdrucks aus einer Liste die ursprüngliche Anfrage nicht vollständig beantworten.
Tomwalsham
2
Ich bin der Meinung, dass ein Fuzzy-Matching-System besser geeignet ist, aber ein benutzerdefinierter Algorithmus scheint übertrieben. Die Verwendung einer Soundex-Metaphon-Kombination scheint genauso gut zu funktionieren wie die Regex-Lösung, sodass weitere unerwartete Schreibweisen möglich sind, während nur handelsübliche Algen verwendet werden.
Tomwalsham
Die Verwendung von Metaphon2 und Metaphon3 führt zu besseren Ergebnissen (dh fast alles in Metaphon2 ist KDF, während Metaphon1 nicht ganz ist). Metaphone3 kostet jedoch etwa 40 Dollar.
Inkognito
27

Verwenden des CPAN-Moduls 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;

Dies erzeugt den folgenden regulären Ausdruck:

(?-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))
Prakash K.
quelle
23

Ich denke, Sie sind damit fertig, die Dinge hier zu komplizieren. Der richtige reguläre Ausdruck ist so einfach wie:

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

Es entspricht der Verkettung der sieben arabischen Unicode-Codepunkte, die das Wort القذافي (dh Gadaffi) bilden.

Staffan Nöteberg
quelle
3
Als nächstes leiten Sie nytimes.com einfach über Google Translate und Bob ist Ihr Onkel.
Robert Rossney
19

Wenn Sie vermeiden möchten, dass Dinge übereinstimmen, die niemand verwendet hat (dh nicht zu ". +" Tendieren), besteht Ihr bester Ansatz darin, einen regulären Ausdruck zu erstellen, der nur alle Alternativen enthält (z. B. (Qadafi | Kadafi | ...)). ) kompilieren Sie das dann zu einem DFA und konvertieren Sie den DFA zurück in einen regulären Ausdruck. Angenommen, eine mäßig sinnvolle Implementierung würde Ihnen einen "komprimierten" regulären Ausdruck geben, der garantiert keine unerwarteten Varianten enthält.

Andrew Cooke
quelle
2
Ich weiß, dass dies theoretisch möglich ist, aber wie würden Sie das in der Praxis tun (zum Beispiel mit einer gemeinsamen dynamischen Sprache)
Rory
3
Ich verstehe die Theorie dahinter, aber wie bei @Rory bin ich auch daran interessiert zu wissen, wie Sie dies in der Praxis tatsächlich tun würden.
Dancavallaro
Ja, ich habe darüber nachgedacht, um eine bessere Antwort zu geben, aber ich bin im Moment ein bisschen beschäftigt. Ich habe einen (hässlichen und schlecht dokumentierten) Code unter code.google.com/p/lepl/source/browse/src/lepl/regexp/core.py , der eine dfa aus einem regulären Ausdruck erstellt (tatsächlich befindet sich der Parser in einer anderen Klasse , aber die harte Arbeit ist da; du gehst regexp -> nfa -> dfa). Von der DFA zu einem regulären Ausdruck zu gelangen ist einfach (glaube ich?).
Andrew Cooke
Tatsächlich ist die Dokumentation dort besser als ich mich erinnere: o) Die Grundidee ist, dass Sie den regulären Ausdruck in Bezug auf die Klassen am oberen Rand der Datei beschreiben. das kann dann ziemlich einfach in eine nfa übersetzt werden (eine nfa ist wirklich nur eine Reihe von Übergängen, die sagen "Wenn Sie diesen Brief bekommen, können Sie hier oder hier hingehen ...", das ist ziemlich einfach zu verstehen). Die dfa ist dann eine Art "erweiterte" Version von der, bei der Sie vermeiden, zurückverfolgen zu müssen. Das macht NfaToDfa (und ist der schwierige Teil). die dfa kann dann aber als regexp selbst betrachtet werden, der als sehr komplexe zeichen geschrieben ist (?!)
andrew cooke
10

Wenn Sie eine konkrete Auflistung aller 30 Möglichkeiten haben, verketten Sie sie einfach alle mit einer Reihe von "Ors". Dann können Sie sicher sein , dass es nur genau den Dingen entspricht, die Sie aufgelistet haben, und nicht mehr. Ihre RE-Engine wird wahrscheinlich in der Lage sein, weiter zu optimieren, und mit 30 Auswahlmöglichkeiten, auch wenn dies nicht der Fall ist, ist es immer noch keine große Sache. Der Versuch, mit der manuellen Umwandlung in eine "clevere" RE herumzuspielen, kann unmöglich besser und möglicherweise schlechter ausfallen.

Jeremy Bowers
quelle
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)

Mit Sicherheit nicht die am besten optimierte Version. Teilen Sie die Silben auf, um die Übereinstimmungen zu maximieren, und stellen Sie gleichzeitig sicher, dass wir keine Fehlalarme erhalten.

Hinterhältig
quelle
7

Nun, da Sie kleine Wörter finden, warum versuchen Sie es nicht mit einer Ähnlichkeitssuchmaschine mit der Levenshtein- Entfernung? Sie können höchstens k Einfügungen oder Löschungen zulassen . Auf diese Weise können Sie die Distanzfunktion auf andere Dinge ändern, die für Ihr spezifisches Problem besser funktionieren. In der simMetrics-Bibliothek stehen viele Funktionen zur Verfügung.

Arnoldo Müller
quelle
4

Eine mögliche Alternative ist das Online-Tool zum Generieren regulärer Ausdrücke aus Beispielen http://regex.inginf.units.it . Gib es eine Chance!

mimmuz
quelle
1

Warum nicht einen gemischten Ansatz? Etwas zwischen einer Liste aller Möglichkeiten und einem komplizierten Regex, der viel zu sehr übereinstimmt.

Bei Regex geht es um Mustervergleich, und ich kann nicht für alle Varianten in der Liste ein Muster sehen. Wenn Sie dies versuchen, werden Sie auch Dinge wie "Gazzafy" oder "Quud'haffi" finden, die höchstwahrscheinlich keine gebrauchte Variante sind und definitiv nicht auf der Liste stehen.

Aber ich kann Muster für einige der Varianten sehen, und so kam ich zu folgendem Ergebnis:

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

Zu Beginn liste ich diejenigen auf, bei denen ich kein Muster sehen kann, gefolgt von einigen Varianten, bei denen es Muster gibt.

Sehen Sie es hier auf www.rubular.com

Stema
quelle
Sie \bsind nur in der ersten und der letzten Alternative enthalten.
Christopher Creutzig
1

Ich weiß, das ist eine alte Frage, aber ...

Keiner dieser beiden regulären Ausdrücke ist der schönste, aber sie sind optimiert und beide passen zu ALL Variationen im ursprünglichen Beitrag .

"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

Ruhe in Frieden, Muammar.

zx81
quelle
0

Nur ein Nachtrag: Sie sollten "Gheddafi" als alternative Schreibweise hinzufügen. So sollte der RE sein

\b[KG]h?[ae]dd?af?fi$\b
Vito De Tullio
quelle
0

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

In Teilen:

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

Hinweis: Ich wollte nur einen Versuch machen.

Dinko Pehar
quelle
-1

Was beginnt sonst noch mit Q, G oder K, hat ad, z oder t in der Mitte und endet mit "fi", nach dem die Leute tatsächlich suchen?

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

Erledigt.

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

Interessant, dass ich herabgestimmt werde. Kann jemand in den Kommentaren einige Fehlalarme hinterlassen?

Strang
quelle
2
Aus einem knackenden Wörterbuch, das ich zufällig herumgesessen habe : 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 . Einige davon sind jedoch keine Fehlalarme .
BMDan
2
Und die Ergänzungen zu dieser Liste, die sich aus dem Ende ergeben, [iy]anstatt nur i:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan