Регулярное выражение для поиска Gadaffi - PullRequest
361 голосов
/ 20 марта 2011

Я пытаюсь найти слово Gadaffi. Какое регулярное выражение лучше всего искать?

Моя лучшая попытка на данный момент:

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

Но мне все еще не хватает некоторых журналов. Есть предложения?

Обновление: я нашел довольно обширный список здесь: http://blogs.abcnews.com/theworldnewser/2009/09/how-many-different-ways-can-you-spell-gaddafi.html

Ответ ниже соответствует всем 30 вариантам:

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

Ответы [ 15 ]

274 голосов
/ 21 марта 2011

Легко ... (Qadaffi|Khadafy|Qadafi| ... ) ... это самодокументированное, поддерживаемое, и, предполагая, что ваш механизм регулярных выражений на самом деле компилирует регулярные выражения (а не интерпретирует их), он будет компилироваться в тот же DFA, который более запутанное решение.

Написание компактных регулярных выражений похоже на использование коротких имен переменных для ускорения программы. Помогает, только если ваш компилятор безмозглый.

137 голосов
/ 20 марта 2011

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

Арабская транскрипция (Wiki говорит) "Qaḏḏāfī", поэтому возможно добавление Q. И одного H ("Каддафи", как упоминается в статье (см. Ниже)).

Кстати, почему в конце регулярного выражения есть $?


Кстати, хорошая статья по теме:

Каддафи, Каддафи или Каддафи? Почему имя ливийского лидера пишется так по-разному? .


EDIT

Чтобы соответствовать всем именам в статье , которую вы упомянули позже , это должно соответствовать им всем. Будем надеяться, что это не будет соответствовать многим другим вещам: D

\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b
45 голосов
/ 21 марта 2011

Одна интересная вещь, которую следует отметить из вашего списка возможных вариантов написания, состоит в том, что для содержащегося списка есть только 3 значения Soundex (если вы игнорируете выброс 'Kazzafi')

G310, K310, Q310

Теперь там есть ложные срабатывания ("Годби" также называется G310), но, комбинируя ограниченные удары метафонов, вы также можете их устранить.

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

Несколько настроек и, скажем, некоторая транслитерация кириллицы, и у вас будет довольно надежное решение.

27 голосов
/ 24 августа 2011

Использование модуля 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;

Это производит следующее регулярное выражение:

(?-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 голосов
/ 22 марта 2011

Я думаю, что вы слишком усложняете вещи здесь. Правильное регулярное выражение так же просто, как:

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

Это соответствует объединению семи арабских кодовых точек Unicode, которые образуют слово القذافي (т.е. Gadaffi).

19 голосов
/ 21 марта 2011

Если вы хотите избежать сопоставления вещей, которые никто не использовал (т.е. избегать стремления к ". +"), Ваш лучший подход - создать регулярное выражение, содержащее только все альтернативы (например, (Qadafi | Kadafi |...)) затем скомпилируйте это в DFA, а затем преобразуйте DFA обратно в регулярное выражение.Предполагая умеренно разумную реализацию, которая даст вам «сжатое» регулярное выражение, которое гарантированно не будет содержать неожиданные варианты.

10 голосов
/ 21 марта 2011

Если у вас есть конкретный список всех 30 возможностей, просто объедините их вместе с кучей «или».Тогда вы можете быть уверены , что оно соответствует только тем вещам, которые вы перечислили, и не более.Ваш двигатель RE, вероятно, сможет оптимизировать в дальнейшем, и, ну, с 30 вариантами выбора, даже если это не так, это все же не имеет большого значения.Попытка возиться с ручным превращением его в «умный» RE не может быть лучше, а может и хуже.

9 голосов
/ 21 марта 2011
(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)

Конечно, не самая оптимизированная версия, разделенная на слоги, чтобы максимизировать совпадения при попытке убедиться, что мы не получаем ложных срабатываний.

7 голосов
/ 22 марта 2011

Ну, так как вы сопоставляете маленькие слова, почему бы вам не попробовать поисковую систему сходства с расстоянием Левенштейна ?Вы можете разрешить максимум k вставок или удалений.Таким образом, вы можете изменить функцию расстояния на другие вещи, которые лучше подходят для вашей конкретной задачи.В библиотеке simMetrics доступно много функций.

4 голосов
/ 14 ноября 2013

Возможной альтернативой является онлайн-инструмент для генерации регулярных выражений из примеров http://regex.inginf.units.it. Дайте ему шанс!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...