regex - regulares - Expresión regular para buscar Gadaffi
javascript regex test (14)
Estoy tratando de buscar la palabra Gadaffi. ¿Cuál es la mejor expresión regular para buscar esto?
Mi mejor intento hasta ahora es:
/b[KG]h?add?af?fi$/b
Pero todavía me faltan algunas revistas. ¿Alguna sugerencia?
Actualización: encontré una lista bastante extensa aquí: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html
La respuesta a continuación coincide con todas las 30 variantes:
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
¿Por qué no hacer un enfoque mixto? Algo entre una lista de todas las posibilidades y un Regex complicado que coincide demasiado.
Regex tiene que ver con la coincidencia de patrones y no puedo ver un patrón para todas las variantes en la lista. Al tratar de hacerlo, también encontrará cosas como "Gazzafy" o "Quud''haffi" que probablemente no sean una variante utilizada y definitivamente no están en la lista.
Pero puedo ver patrones para algunas de las variantes, por lo que terminé con esto:
/b(?:Gheddafi|Gathafi|Kazzafi|Kad''afi|Qadhdhafi|Qadthafi|Qudhafi|Qu?athafi|[KG]h?add?h?aff?[iy]|Qad[dh]?afi)/b
Al principio, enumero aquellos en los que no puedo ver un patrón, luego seguí algunas variantes donde hay patrones.
www.rubular.com aquí en www.rubular.com
¿Qué más comienza con Q, G o K, tiene ad, z o t en el medio y termina en "fi" que la gente realmente busca?
//b[GQK].+[dzt].+fi/b/i
Hecho.
>>> print re.search(a, "Gadasadasfiasdas") != None
False
>>> print re.search(a, "Gadasadasfi") != None
True
>>> print re.search(a, "Qa''dafi") != None
True
Interesante que me están bajando las votaciones. ¿Alguien puede dejar algunos falsos positivos en los comentarios?
Bueno, ya que estás uniendo palabras pequeñas, ¿por qué no intentas un motor de búsqueda de similitud con la distancia de Levenshtein ? Puede permitir como máximo k inserciones o supresiones. De esta manera, puede cambiar la función de distancia a otras cosas que funcionen mejor para su problema específico. Hay muchas funciones disponibles en la biblioteca simMetrics.
Creo que estás sobre complicando las cosas aquí. La expresión regular correcta es tan simple como:
/u0627/u0644/u0642/u0630/u0627/u0641/u064a
Coincide con la concatenación de los siete puntos del código árabe Unicode que forman la palabra القذافي (es decir, Gadaffi).
Fácil ... (Qadaffi|Khadafy|Qadafi|
... )
... es auto-documentado, mantenible, y asumiendo que su motor de expresiones regulares compila expresiones regulares (en lugar de interpretarlas), compilará en la misma DFA que un Una solución más confusa lo haría.
Escribir expresiones regulares compactas es como usar nombres cortos de variables para acelerar un programa. Solo ayuda si tu compilador tiene muerte cerebral.
Sé que esta es una vieja pregunta, pero ...
Ninguna de estas dos expresiones regulares es la más bonita, pero están optimizadas y ambas coinciden con TODAS las variaciones en la publicación original.
"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
Descansa en paz, Muammar.
Si desea evitar hacer coincidir las cosas que nadie ha usado (es decir, evitar la tendencia a ". +"), Su mejor enfoque sería crear una expresión regular que sea todas las alternativas (por ejemplo, (Qadafi | Kadafi | ...) ) luego compile eso en un DFA, y luego vuelva a convertir el DFA en una expresión regular. Suponiendo una implementación moderadamente sensible que le daría una expresión regular "comprimida" que garantice no contener variantes inesperadas.
Si tiene una lista concreta de las 30 posibilidades, solo concatene todas juntas con un montón de "ors". Entonces puede estar seguro de que solo coincide con las cosas exactas que ha enumerado, y no más. Es probable que su motor RE pueda optimizar aún más y, bueno, con 30 opciones, aunque no sea así, todavía no es un gran problema. Intentar manipularlo manualmente y convertirlo en un RE "inteligente" no puede resultar mejor y puede empeorar.
Solo un addendum: debe agregar "Gheddafi" como ortografía alternativa. Así que el RE debería ser
/b[KG]h?[ae]dd?af?fi$/b
Una cosa interesante a tener en cuenta de su lista de ortografías potenciales es que solo hay 3 valores de Soundex para la lista contenida (si ignora el valor ''Kazzafi'')
G310, K310, Q310
Ahora, hay falsos positivos ahí (''Godby'' también es G310), pero combinando los limitados éxitos de los metáfonos, también puedes eliminarlos.
<?
$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;
?>
Unos pocos ajustes, y digamos algo de transliteración cirílica, y tendrás una solución bastante robusta.
Una posible alternativa es la herramienta en línea para generar expresiones regulares a partir de ejemplos http://regex.inginf.units.it . ¡Dame una oportunidad!
Usando el módulo CPAN Regexp :: Ensamble :
#!/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;
Esto produce la siguiente expresión regular:
(?-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))
/b[KGQ]h?add?h?af?fi/b
La transcripción en árabe es (Wiki dice) "Qaḏḏāfī", así que tal vez agregue una Q. Y una H ("Gadhafi", como se menciona en el artículo (ver más abajo)).
Por cierto, ¿por qué hay un $
al final de la expresión regular?
Por cierto, buen artículo sobre el tema:
Gaddafi, Kadafi, o Gadafi? ¿Por qué el nombre del líder libio está escrito de tantas maneras diferentes? .
EDITAR
Para hacer coincidir todos los nombres en el artículo que mencionaste más adelante , esto debería coincidir con todos. Esperemos que no coincida con muchas otras cosas: D
/b(Kh?|Gh?|Qu?)[aeu](d[''dt]?|t|zz|dhd)h?aff?[iy]/b
(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)
Ciertamente, no es la versión más optimizada, dividida en sílabas para maximizar las coincidencias mientras se intenta asegurarse de que no obtengamos falsos positivos.