Регулярное выражение для поиска Гадаффи

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

Моя лучшая попытка:

\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

Ответ 1

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

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

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


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

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

ИЗМЕНИТЬ

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

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

Ответ 2

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

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

Ответ 3

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

G310, K310, Q310

Теперь есть ложные срабатывания ( "Godby" также является 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;
?>

Несколько настроек, и давайте скажем, какую-то кириллическую транслитерацию, и у вас будет довольно надежное решение.

Ответ 4

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

Ответ 5

Думаю, ты слишком усложняешь ситуацию. Правильное регулярное выражение так же просто, как:

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

Ответ 11

Почему бы не сделать смешанный подход? Что-то между списком всех возможностей и сложным Regex, который слишком много соответствует.

Regex - это сопоставление с образцом, и я не вижу шаблон для всех вариантов в списке. Пытаясь сделать это, также найдутся такие вещи, как "Газзафи" или "Куддхаффи", которые, скорее всего, не используются и, безусловно, не входят в список.

Но я могу видеть шаблоны для некоторых вариантов, и поэтому я закончил с этим:

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

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

См. здесь www.rubular.com

Ответ 12

Я знаю, что это старый вопрос, но...

Ни одно из этих двух регулярных выражений не является самым красивым, но они оптимизированы и оба соответствуют ALL вариантам исходного сообщения.

"Маленькая красавица" # 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)

"Маленькая красавица" # 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

Отдых в мире, Муаммар.

Ответ 13

Просто добавление: вы должны добавить "Геддафи" в качестве альтернативного написания. Таким образом, RE должен быть

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

Ответ 14

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

По частям:

  • [GQK]
  • [Ах] +
  • [Dtez] +
  • \ '?
  • [Adhz] +
  • е {1,2} (я | у)

Примечание: просто хотел дать шанс на это.

Ответ 15

Что еще начинается с Q, G или K, имеет d, z или t в середине и заканчивается "fi" для людей на самом деле для поиска?

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

Готово.

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

Интересно, что меня забирают. Может ли кто-нибудь оставить некоторые ложные срабатывания в комментариях?