Expression régulière pour rechercher Kadaffi

361

J'essaie de chercher le mot Gadaffi. Quelle est la meilleure expression régulière pour rechercher cela?

Jusqu'à présent, ma meilleure tentative est:

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

Mais il me semble toujours manquer certains journaux. Aucune suggestion?

Mise à jour: j'ai trouvé une liste assez complète ici: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

La réponse ci-dessous correspond aux 30 variantes:

Kadaffi
Kadafi
Kadafy
Kadhafi
Kadhafi
Kadhafi
Kadhafi
Gathafi
Ghadaffi
Khadafi
Ghaddafi
Ghaddafy
Gheddafi
Kadaffi
Kadafi
Kadhafi
Kadhafi
Kazzafi
Khadaffy
Khadafy
Khaddafi
Kadafi
Kadhafi
Kadhafi
Qadhdhafi
Qadthafi
Qathafi
Quathafi
Qudhafi
Kad'afi
SiggyF
la source
8
Quels sont ceux qui vous manquent? Et où cherchez-vous, y a-t-il une recherche sur le Web avec regex?
Czechnology
43
Il y a toujours de nouvelles revues publiées, donc si elles continuent d'écrire sur Gadaffi, vous aurez tendance à .+être la seule expression régulière valide.
moinudin
30
J'ai trouvé que cette image aide avec les différentes orthographes: upload.wikimedia.org/math/6/1/f/…
KLee1
24
Comme d'habitude, Lisp a implémenté ce premier - foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp ( faites défiler à mi-chemin)
Daniel S. Sterling
7
@Daniel Sterling: en fait, le test Khadafy fait partie de la suite de tests GNU grep depuis le commit initial sur RCS (Tue Nov 3 21:38:52 1998 +0000), et est probablement encore plus ancien que ça!
Paolo Bonzini

Réponses:

138

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

La transcription en arabe est (Wiki dit) "Qaḏḏāfī", donc peut-être en ajoutant un Q. Et un H ("Kadhafi", comme le mentionne l'article (voir ci-dessous)).

Btw, pourquoi y a-t-il un $à la fin de l'expression régulière?


Btw, bel article sur le sujet:

Kadhafi, Kadafi ou Kadhafi? Pourquoi le nom du chef libyen est-il orthographié de différentes manières? .


ÉDITER

Pour faire correspondre tous les noms de l' article que vous avez mentionné plus tard , cela devrait tous les faire correspondre. Espérons juste que cela ne correspondra pas à beaucoup d'autres choses: D

\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b
Czechnology
la source
Le $ est faux, je faisais d'abord correspondre la fin des lignes, j'ai oublié de le supprimer.
SiggyF
Correspond dégalement à un ḏ?
SiggyF
2
@ DiggyF, non, je pensais juste que si la transcription arabe le disait Qaḏḏāfī, l'expression régulière devrait aussi vérifier Qaddafi. Si vous souhaitez également rechercher la transcription arabe, recherchez-la simplement - je ne pense pas qu'il existe d'autres variantes de la transcription arabe, uniquement des transcriptions anglaises.
Czechnology
@DiggyF, j'ai édité dans une expression régulière plus longue qui correspond à tous les noms dans l'article que vous avez publié (sauf les deux avec ?au lieu de lettres). Cela pourrait être exagéré.
Czechnology
2
Cela correspond également à «Quuzzafi» et à un tas d'autres faux positifs, bien que je suppose que dans la recherche dans les reportages, etc., cela n'aura pas beaucoup d'importance.
ben w
275

Facile ... (Qadaffi|Khadafy|Qadafi|... )... il est auto-documenté, maintenable, et en supposant que votre moteur d'expression régulière compile réellement des expressions régulières (plutôt que de les interpréter), il compilera vers le même DFA qu'une solution plus obscure.

Écrire des expressions régulières compactes, c'est comme utiliser des noms de variables courts pour accélérer un programme. Cela n'aide que si votre compilateur est mort de cervelle.

Chris Pacejo
la source
23
Très bonne réponse! Les gens utilisent les expressions régulières beaucoup plus souvent qu'ils ne se soucient de la façon dont ils fonctionnent réellement.
Thomas Ahle
3
J'aime aussi la simplicité de cette solution, mais je suis surpris que cela se compile vers le même DFA. Avez-vous un lien qui en parle? Intuitivement, cela semble être moins efficace que l'expression rationnelle précédemment conçue ou la réponse ci-dessous qui suggère d'utiliser le module perge Regexp :: Assemble sur la même liste de noms ou.
Rian Sanderson
6
-1 L'intérêt d'une expression régulière est de réduire ce qui peut souvent être - comme c'est le cas dans ce cas - une très longue liste d'alternatives à une formule relativement courte. Le résultat peut souvent s'exécuter plus rapidement que ce qui est essentiellement une recherche exhaustive non optimisée.
martineau
7
Vous avez raison, l'objectif des expressions régulières est de fournir une représentation claire et compacte pour un large ensemble de valeurs. Mais le concept de base est de présenter une expression régulière et de dire "tout ce qui correspond à cela est bon". Autrement dit, cela suppose que vous avez la liberté d'inclure quoi que ce soit de systématique. Ici, nous avons la situation inverse: les variantes orthographiques (et les variations qui n'apparaissent jamais) ne sont que de ce côté du «tout à fait aléatoire». Les tentatives élaborées de "compact" obtiennent des points très bas pour "clair"!
jackr
1
Consultez également l'algorithme Aho-Corasick, qui est optimal pour la recherche simultanée de chaînes: en.wikipedia.org/wiki/…
Thomas Ahle
45

Une chose intéressante à noter de votre liste d'orthographes potentiels est qu'il n'y a que 3 valeurs Soundex pour la liste contenue (si vous ignorez la valeur aberrante 'Kazzafi')

G310, K310, Q310

Maintenant, il y a des faux positifs là-dedans ('Godby' est aussi G310), mais en combinant également les hits limités du métaphone, vous pouvez les éliminer.

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

Quelques ajustements, et disons une translittération cyrillique, et vous aurez une solution assez robuste.

tomwalsham
la source
2
Veuillez noter que soundex est spécialisé en anglais, il existe d'autres algorithmes phonétiques pour d'autres langues avec des règles de prononciation différentes
Incognito
8
Bien que cela soit vrai, nous sommes dans une situation étrange ici. La demande principale était "J'essaie de chercher le mot Kadaffi", mais je pense que l'expression régulière était un hareng rouge. Il n'y a pas de livre de règles sur la translittération arabe> latin, et en tant que tel, inverser une expression régulière d'une liste ne répondra pas entièrement à la demande d'origine.
tomwalsham
2
Je pense qu'un système de correspondance floue est mieux adapté, mais un algorithme personnalisé semble exagéré. L'utilisation d'un combo soundex-métaphone semble fonctionner aussi bien que la solution regex, permettant d'autres orthographes imprévues tout en utilisant simplement des algos standard.
tomwalsham
L'utilisation du métaphone2 et du métaphone3 conduit à de meilleurs résultats (c'est-à-dire que presque tout dans le métaphone2 est KDF, alors que le métaphone1 n'est pas tout à fait). Cependant, Metaphone3 coûte environ 40 dollars.
Incognito
27

Utilisation du module 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;

Cela produit l'expression régulière suivante:

(?-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
la source
23

Je pense que vous avez trop compliqué les choses ici. L'expression correcte est aussi simple que:

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

Il correspond à la concaténation des sept points de code Unicode arabes qui forment le mot القذافي (c'est-à-dire Gadaffi).

Staffan Nöteberg
la source
3
Ensuite, dirigez simplement nytimes.com via Google Translate et Bob est votre oncle.
Robert Rossney
19

Si vous voulez éviter de faire correspondre des choses que personne n'a utilisées (c'est-à-dire éviter de tendre vers ". +"), Votre meilleure approche serait de créer une expression régulière qui n'est que toutes les alternatives (par exemple (Qadafi | Kadafi | ...) ), puis compilez-le en DFA, puis reconvertissez-le en une expression régulière. En supposant une implémentation modérément raisonnable qui vous donnerait une expression régulière "compressée" qui est garantie de ne pas contenir de variantes inattendues.

Andrew Cooke
la source
2
Je sais que c'est théoriquement possible, mais comment feriez-vous cela dans la pratique (en utilisant par exemple un langage dynamique commun)
Rory
3
Je comprends la théorie derrière cela, mais comme @Rory, je suis également intéressé de savoir comment vous le feriez dans la pratique.
dancavallaro
oui, j'ai pensé à le faire, pour donner une meilleure réponse, mais je suis un peu occupé en ce moment. j'ai du code (laid et mal documenté) sur code.google.com/p/lepl/source/browse/src/lepl/regexp/core.py qui construit un dfa à partir d'un regexp (en fait, l'analyseur est dans une autre classe , mais le travail acharné est là; vous allez regexp -> nfa -> dfa). passer du dfa à un regexp est facile (je pense?).
Andrew Cooke
en fait, la documentation y est meilleure que je ne m'en souviens: o) l'idée de base est que vous décrivez l'expression rationnelle en termes de classes près du haut du fichier. cela peut alors être traduit assez facilement en nfa (un nfa n'est en fait qu'un ensemble de transitions disant "si vous obtenez cette lettre, vous pouvez aller ici ou ici ..." c'est assez facile à comprendre). le dfa est alors une sorte de version "élargie" de celui où vous évitez d'avoir à revenir en arrière; cela est fait par NfaToDfa (et c'est la partie difficile). le dfa peut alors être considéré comme un regexp lui-même qui est écrit comme des jeux de caractères très complexes (?!)
andrew cooke
10

Si vous avez une liste concrète des 30 possibilités, il vous suffit de les concaténer avec un tas de "or". Ensuite, vous pouvez être sûr qu'il ne correspond qu'aux éléments exacts que vous avez répertoriés, et pas plus. Votre moteur RE sera probablement en mesure d'optimiser davantage et, bien, avec 30 choix même si ce n'est pas le cas, ce n'est toujours pas un gros problème. Essayer de jouer avec le transformer manuellement en un RE "intelligent" ne peut pas se révéler mieux et peut se révéler pire.

Jeremy Bowers
la source
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)

Certainement pas la version la plus optimisée, divisée en syllabes pour maximiser les correspondances tout en essayant de ne pas obtenir de faux positifs.

Sournois
la source
7

Eh bien, puisque vous faites correspondre de petits mots, pourquoi n'essayez-vous pas un moteur de recherche de similitude avec la distance Levenshtein ? Vous pouvez autoriser au plus k insertions ou suppressions. De cette façon, vous pouvez changer la fonction de distance pour d'autres choses qui fonctionnent mieux pour votre problème spécifique. De nombreuses fonctions sont disponibles dans la bibliothèque simMetrics.

Arnoldo Muller
la source
4

Une alternative possible est l'outil en ligne pour générer des expressions régulières à partir d'exemples http://regex.inginf.units.it . Donnez-lui une chance!

mimmuz
la source
1

Pourquoi ne pas faire une approche mixte? Quelque chose entre une liste de toutes les possibilités et une Regex compliquée qui correspond beaucoup trop.

Regex concerne la correspondance de modèles et je ne vois pas de modèle pour toutes les variantes de la liste. En essayant de le faire, vous trouverez également des choses comme "Gazzafy" ou "Quud'haffi" qui ne sont probablement pas une variante utilisée et qui ne figurent définitivement pas sur la liste.

Mais je peux voir des modèles pour certaines des variantes, et je me suis donc retrouvé avec ceci:

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

Au début, j'énumère ceux où je ne vois pas de motif, puis quelques variantes où il y a des motifs.

Voir ici sur www.rubular.com

stema
la source
Vous \bn'êtes inclus que dans la première et la dernière alternative.
Christopher Creutzig
1

Je sais que c'est une vieille question, mais ...

Aucun de ces deux regex n'est le plus joli, mais ils sont optimisés et tous les deux correspondent à TOUTES les variations dans le message d'origine.

"Petite beauté" # 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)

"Petite beauté" # 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

Repose en paix, Mouammar.

zx81
la source
0

Juste un addendum: vous devez ajouter "Gheddafi" comme orthographe alternative. Donc, le RE devrait être

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

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

En pièces détachées:

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

Remarque: Je voulais juste donner un coup de feu à cela.

Dinko Pehar
la source
-1

Quoi d'autre commence par Q, G ou K, a ad, z ou t au milieu, et se termine par "fi" que les gens recherchent réellement ?

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

Terminé.

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

Intéressant que je reçois des votes négatifs. Quelqu'un peut-il laisser des faux positifs dans les commentaires?

Hank
la source
2
A partir d' un dictionnaire de fissuration que j'arrive d'avoir assis autour: 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 . Certains d'entre eux ne sont cependant pas de faux positifs.
BMDan
2
Et les ajouts à cette liste qui résultent de la fin au [iy]lieu de simplement i:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan