J'essaie de chercher le mot gadget. Quelle est la meilleure expression régulière pour rechercher cela?
Ma meilleure tentative jusqu'à présent est:
\b[KG]h?add?af?fi$\b
Mais il me manque encore des revues. Aucune suggestion?
Mise à jour: J'ai trouvé une liste assez longue ici: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html
La réponse ci-dessous correspond à toutes les 30 variantes:
Kadhafi Kadhafi Gadafy Kadhafi Kadhafy Kadhafi Kadhafi Gathafi Ghadafi Ghadafi Ghaddafi Ghaddafi .Gheddafi Kadaffi Kadafi Kaddafi Kadhafi Kazzafi Khadafy Khadafy Khaddafi Qadafi Kaddafi Kadafi Qadhafi Kadthafi Qathafi Quathafi Qudhafi Kad'afi
\b[KGQ]h?add?h?af?fi\b
La transcription en arabe est (Wiki dit) "Qaḏḏāfī", alors peut-être ajouter un Q. Et un H ("Kadhafi", comme mentionné dans l'article (voir ci-dessous)).
Btw, pourquoi y at-il un $
à la fin de la regex?
Btw, Nice article sur le sujet:
MODIFIER
Pour faire correspondre tous les noms de l'article que vous avez mentionné plus tard , cela doit correspondre à tous. Espérons que cela ne correspondra pas à beaucoup d'autres choses: D
\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b
Facile ... (Qadaffi|Khadafy|Qadafi|
...)
... auto-documenté, maintenable, et en supposant que votre moteur d'expressions rationnelles compile des expressions régulières (plutôt que de les interpréter), il compilera dans le même DFA qu'une solution plus complexe.
Écrire des expressions régulières compactes revient à utiliser des noms de variable courts pour accélérer un programme. Cela n'aidera que si votre compilateur est mort cérébralement.
Une chose intéressante à noter dans votre liste d'orthographes potentielles est qu'il n'y a que 3 valeurs Soundex pour la liste contenue (si vous ignorez la valeur aberrante «Kazzafi»).
G310, K310, Q310
À présent, il y a des faux positifs («Godby» est également le G310), mais en combinant également les hits de métaphone limités, 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.
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))
Je pense que vous compliquez les choses ici. La regex 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).
Si vous souhaitez éviter de faire correspondre des éléments que personne n'a utilisés (par exemple, ne pas tendre vers ". +"), Votre meilleure approche serait de créer une expression régulière ne contenant que toutes les alternatives (par exemple. (Qadafi | Kadafi | ...) ) puis compilez-le dans un DFA, puis reconvertissez-le en une expression régulière. En supposant une implémentation moyennement sensible qui vous donnerait une expression régulière "compressée" garantissant de ne pas contenir de variantes inattendues.
Si vous avez une liste concrète des 30 possibilités, il vous suffit de les concaténer avec un groupe de "or". Ensuite, vous pouvez être sûr que cela correspond uniquement aux éléments que vous avez énumérés, sans plus. Votre moteur RE sera probablement en mesure d’optimiser davantage et, avec 30 choix, même si ce n’est pas le cas, ce n’est pas grave. Essayer de le modifier manuellement en le transformant en une ER "intelligente" ne peut pas être meilleur et peut devenir pire.
(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 d’éviter les faux positifs.
Puisque vous faites correspondre de petits mots, pourquoi ne pas essayer un moteur de recherche par similarité avec la distance { Levenshtein ? Vous pouvez autoriser au maximum k des insertions ou des suppressions. De cette façon, vous pouvez modifier la fonction de distance en choisissant d’autres éléments qui fonctionnent mieux pour votre problème spécifique. De nombreuses fonctions sont disponibles dans la bibliothèque simMetrics.
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!
Pourquoi ne pas faire une approche mixte? Quelque chose entre une liste de toutes les possibilités et un regex compliqué qui correspond beaucoup trop.
Regex est sur la correspondance de motif et je ne peux pas voir un motif pour toutes les variantes de la liste. En essayant de le faire, vous trouverez aussi des choses comme "Gazzafy" ou "Quud'haffi" qui ne sont probablement pas une variante utilisée et qui ne sont définitivement pas sur la liste.
Mais je peux voir des modèles pour certaines des variantes et je me suis 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, suivi de quelques variantes où il y a des motifs.
Voir ici sur www.rubular.com
Je sais que c'est une vieille question, mais ...
Aucune de ces deux expressions rationnelles n'est la plus jolie, mais elles sont optimisées et toutes les deux correspondent à TOUTES aux variations de la publication 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.
Juste un addenda: vous devriez ajouter "Gheddafi" comme orthographe alternative. Donc, l'ER devrait être
\b[KG]h?[ae]dd?af?fi$\b
Qu'est-ce qui commence par Q, G ou K, a d, z ou t au milieu et se termine par "fi" les personnes en fait recherche?
/\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 un vote négatif. Quelqu'un peut-il laisser des faux positifs dans les commentaires?
[GQK] [ahu] + [dtez] +\'? [Adhz] + f {1,2} (i | y)
En pièces:
Note: je viens d’apprendre l’expression rationnelle et je voulais essayer. Corrige une petite erreur plus tard