Espressione regolare per cercare Gadaffi


361

Sto cercando di cercare la parola Gadaffi. Qual è la migliore espressione regolare per cercarla?

Il mio miglior tentativo finora è:

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

Ma mi sembrano ancora mancare alcune riviste. Eventuali suggerimenti?

Aggiornamento: ho trovato un elenco piuttosto ampio qui: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

La risposta di seguito corrisponde a tutte le 30 varianti:

Gheddafi
Gheddafi
Gheddafi
Gheddafi
Gaddafy
Gaddhafi
Gheddafi
Gheddafi
Gheddafi
Gheddafi
Gheddafi
Ghaddafy
Gheddafi
Kadaffi
Kadafi
Gheddafi
Gheddafi
Kazzafi
Khadaffy
Gheddafi
Gheddafi
Qadafi
Gheddafi
Gheddafi
Gheddafi
Qadthafi
Qathafi
Quathafi
Qudhafi
Kad'afi

8
Quali ti perdi? E dove stai cercando, c'è una ricerca web con regex?
Cecologia

43
Ci sono sempre nuove riviste pubblicate, quindi se continuano a scrivere su Gadaffi tenderai ad .+essere l'unica espressione regolare valida.
Moinudin,

30
Ho scoperto che questa immagine aiuta con le diverse ortografie: upload.wikimedia.org/math/6/1/f/…
KLee1

24
Come al solito, Lisp ha implementato questa prima versione: foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp (scorri a metà)
Daniel S. Sterling

7
@Daniel Sterling: in realtà, il test di Khadafy fa parte del GNU grep testuite dal primo commit in RCS (mar 3 novembre 21:38:52 1998 +0000), ed è probabilmente ancora più vecchio di così!
Paolo Bonzini,

Risposte:


138

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

La trascrizione araba è (dice Wiki) "Qaḏḏāfī", quindi forse aggiungendo una Q. E una H ("Gheddafi", come menziona l'articolo (vedi sotto)).

A proposito, perché c'è un $alla fine della regex?


A proposito, bell'articolo sull'argomento:

Gheddafi, Gheddafi o Gheddafi? Perché il nome del leader libico è scritto in così tanti modi diversi? .


MODIFICARE

Per abbinare tutti i nomi nell'articolo che hai citato in seguito , questo dovrebbe corrispondere a tutti. Speriamo solo che non corrisponda a molte altre cose: D

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

$ È errato, stavo corrispondendo prima alla fine delle righe, ho dimenticato di rimuoverlo.
SiggyF

Fa danche corrispondere una D?
SiggyF

2
@DiggyF, no, pensavo solo che se la trascrizione araba dice che anche Qaḏḏāfīla regex dovrebbe controllare Qaddafi. Se vuoi cercare anche la trascrizione araba, cerca quella - non penso che ci siano più varianti della trascrizione araba, solo delle trascrizioni inglesi.
Czechnology,

@DiggyF, ho modificato una regex più lunga che corrisponde a tutti i nomi nell'articolo che hai pubblicato (tranne i due con ?anziché lettere). Potrebbe essere eccessivo però.
Cecologia

2
Ciò corrisponde anche a "Quuzzafi" e ad un gruppo di altri falsi positivi, anche se suppongo che nella ricerca di notizie, ecc., Ciò non importerà molto.
ben w,

275

Facile ... (Qadaffi|Khadafy|Qadafi|... )... è auto-documentato, gestibile e supponendo che il tuo motore regexp compili effettivamente espressioni regolari (piuttosto che interpretarle), verrà compilato nello stesso DFA che una soluzione più offuscata.

Scrivere espressioni regolari compatte è come usare nomi di variabili brevi per velocizzare un programma. Aiuta solo se il tuo compilatore è morto nel cervello.


23
Bella risposta! Le persone usano le espressioni regolari molto più spesso di quanto si preoccupino di come funzionano effettivamente.
Thomas Ahle,

3
Mi piace molto anche la semplicità di questa soluzione, ma sono sorpreso che questo si compili fino allo stesso DFA. Hai un link che ne parla? Intuitivamente sembra che potrebbe essere meno efficiente del regex precedentemente creato o della risposta che segue che suggerisce di usare il modulo perl Regexp :: Assemble nello stesso elenco di nomi.
Rian Sanderson,

6
-1 Il punto centrale di una regex è ridurre ciò che spesso può essere - come in questo caso - un elenco molto lungo di alternative a una formula relativamente breve. Il risultato può spesso essere eseguito più velocemente di quello che è essenzialmente una ricerca esaustiva non ottimizzata.
martineau,

7
Hai ragione, il punto di regex è quello di fornire una rappresentazione compatta e chiara per un ampio insieme di valori. Ma il concetto di base è presentare una regex e dire "tutto ciò che corrisponde a questo è buono". Cioè, si presume che tu abbia la libertà di includere qualcosa di sistematico. Qui abbiamo la situazione opposta: le varianti ortografiche (e le variazioni che non appaiono mai) sono solo a malapena questo lato di "assolutamente casuale". Gli elaborati tentativi di "compatto" ottengono punti molto bassi per "chiaro"!
jackr,

1
Controlla anche l'algoritmo Aho-Corasick, che è ottimale per la ricerca simultanea di stringhe: en.wikipedia.org/wiki/…
Thomas Ahle

45

Una cosa interessante da notare dal tuo elenco di potenziali ortografia è che ci sono solo 3 valori Soundex per l'elenco contenuto (se ignori il 'Kazzafi' anomalo)

G310, K310, Q310

Ora, ci sono falsi positivi lì dentro ('Godby' è anche G310), ma combinando anche i colpi limitati del metafono, puoi eliminarli.

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

Alcune modifiche, e diciamo un po 'di traslitterazione cirillica, e avrai una soluzione abbastanza robusta.


2
Nota, soundex è specializzato in inglese, esistono altri algoritmi fonetici per altre lingue con regole di pronuncia diverse
Incognito

8
Anche se questo è vero, qui ci troviamo in una situazione strana. La richiesta principale era "Sto cercando di cercare la parola Gadaffi", ma sento che la regex era un'aringa rossa. Non esiste un libro di regole sulla traslitterazione in arabo-> latino e, in quanto tale, invertire una regex da un elenco non risponderà completamente alla richiesta originale.
Tomwalsham,

2
Sento che un sistema di corrispondenza fuzzy è più adatto, ma un algoritmo personalizzato sembra eccessivo. L'uso di una combo soundex-metaphone sembra funzionare così come la soluzione regex, consentendo ulteriori ortografie impreviste mentre si usano ancora algoritmi standard.
Tomwalsham,

L'uso di metaphone2 e metaphone3 porta a risultati migliori (ovvero, quasi tutto in metaphone2 è KDF, dove metaphone1 non è del tutto). Metaphone3, tuttavia, costa circa 40 dollari.
Incognito

27

Utilizzando il modulo 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;

Questo produce la seguente espressione regolare:

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

Penso che tu stia complicando le cose qui. Il regex corretto è semplice come:

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

Corrisponde alla concatenazione dei sette punti del codice Unicode arabo che formano la parola القذافي (cioè Gadaffi).


3
Successivamente, basta pipe nytimes.com tramite Google Translate e Bob è tuo zio.
Robert Rossney,

19

Se vuoi evitare di abbinare cose che nessuno ha usato (cioè evitare di tendere verso ". +") Il tuo approccio migliore sarebbe quello di creare un'espressione regolare che sia solo tutte le alternative (es. (Qadafi | Kadafi | ...) ) quindi compilarlo in un DFA, quindi riconvertire il DFA in un'espressione regolare. Supponendo un'implementazione moderatamente ragionevole che ti darebbe un'espressione regolare "compressa" che è garantita per non contenere varianti impreviste.


2
So che è possibile dal punto di vista fisico, ma come lo faresti in pratica (usando ad esempio un linguaggio dinamico comune)
Rory

3
Capisco la teoria dietro questo, ma come @Rory, sono anche interessato a sapere come lo faresti in pratica.
dancavallaro,

sì, ho pensato di farlo, per dare una risposta migliore, ma al momento sono un po 'impegnato. ho del codice (brutto e scarsamente documentato) su code.google.com/p/lepl/source/browse/src/lepl/regexp/core.py che costruisce una dfa da un regexp (in realtà, il parser è in un'altra classe , ma il duro lavoro è lì; vai regexp -> nfa -> dfa). passare dalla Dfa a una regexp è facile (penso?).
Andrew Cooke,

in realtà, la documentazione è migliore di quella che ricordo: o) l'idea di base è che descrivi il regexp in termini di classi vicino all'inizio del file. che poi può essere tradotto abbastanza facilmente in una nfa (una nfa è in realtà solo una serie di transizioni che dicono "se ricevi questa lettera, allora puoi andare qui o qui ..." è abbastanza facile da capire). il dfa è quindi una specie di versione "espansa" di quella in cui si continua a evitare di tornare indietro; fatto da NfaToDfa (ed è la parte difficile). la dfa può quindi essere considerata come una regexp stessa scritta come set di caratteri molto complessi (?!)
andrew cooke

10

Se hai un elenco concreto di tutte e 30 le possibilità, concatenale tutte insieme con un gruppo di "ors". Quindi puoi essere sicuro che corrisponde solo alle cose esatte che hai elencato e non di più. Il tuo motore RE sarà probabilmente in grado di ottimizzare ulteriormente, e, beh, con 30 scelte anche se non lo è, non è ancora un grosso problema. Cercare di armeggiare trasformandolo manualmente in un RE "intelligente" non può andare meglio e può andare peggio.


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)

Certamente non la versione più ottimizzata, divisa in sillabe per massimizzare le partite mentre proviamo ad assicurarci di non avere falsi positivi.


7

Bene, poiché stai abbinando le parole piccole, perché non provi un motore di ricerca di somiglianza con la distanza di Levenshtein ? Puoi consentire al massimo k inserimenti o eliminazioni. In questo modo è possibile modificare la funzione di distanza su altre cose che funzionano meglio per il problema specifico. Ci sono molte funzioni disponibili nella libreria simMetrics.



1

Perché non seguire un approccio misto? Qualcosa tra un elenco di tutte le possibilità e un complicato Regex che corrisponde troppo.

Regex riguarda la corrispondenza dei motivi e non riesco a vedere un motivo per tutte le varianti nell'elenco. Provando a farlo, troverai anche cose come "Gazzafy" o "Quud'haffi" che molto probabilmente non sono una variante usata e sicuramente non nella lista.

Ma posso vedere modelli per alcune delle varianti, e così ho finito con questo:

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

All'inizio elencherò quelli in cui non riesco a vedere uno schema, quindi seguo alcune varianti in cui ci sono schemi.

Guardalo qui su www.rubular.com


Il tuo \bsono inclusi solo nel primo e gli ultimi alternative.
Christopher Creutzig,

1

So che questa è una vecchia domanda, ma ...

Nessuna di queste due regex è la più bella, ma sono ottimizzate ed entrambe corrispondono a TUTTE le varianti del post originale.

"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

Riposa in pace, Muammar.


0

Solo un addendum: dovresti aggiungere "Gheddafi" come ortografia alternativa. Quindi l'IR dovrebbe essere

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

0

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

In parti:

  • [GQK]
  • + [Ahu]
  • + [Dtez]
  • \ '?
  • [Adhz] +
  • f {1,2} (i | y)

Nota: volevo solo provare.


-1

Cos'altro inizia con Q, G o K, ha annuncio, z o t nel mezzo e termina in "fi" che le persone effettivamente cercano?

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

Fatto.

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

Interessante il fatto che mi sto sottovalutando. Qualcuno può lasciare alcuni falsi positivi nei commenti?


2
Da un dizionario di cracking che mi capita di avere seduti intorno: 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 . Alcuni di questi non sono falsi positivi, però.
BMDan,

2
E le aggiunte a quella lista che risultano dalla conclusione [iy]invece che semplicemente i:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.