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

369

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

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

\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
  • 2
    Откуда ты знаешь, что тебе не хватает некоторых журналов?
  • 8
    Какие из них вам не хватает? И где вы ищете, есть ли веб-поиск с помощью регулярных выражений?
Показать ещё 18 комментариев
Теги:
search

14 ответов

137
Лучший ответ

\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
  • 0
    $ Неправильный, я сначала сопоставил конец строки, забыл удалить его.
  • 0
    d также соответствует ḏ?
Показать ещё 5 комментариев
256

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

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

  • 23
    Отличный ответ! Люди используют регулярные выражения гораздо чаще, чем заботятся о том, как они на самом деле работают.
  • 3
    Мне также очень нравится простота этого решения, но я удивлен, что это скомпилируется в тот же DFA. У вас есть ссылка, которая говорит об этом? Интуитивно кажется, что это может быть менее эффективно, чем ранее созданное регулярное выражение или ответ ниже, который предлагает использовать модуль Perl Regexp :: Assemble в том же списке имен or'd.
Показать ещё 5 комментариев
43

Интересно отметить из вашего списка потенциальных написаний, что только 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;
?>

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

  • 2
    Обратите внимание, что soundex специализируется на английском языке, существуют другие фонетические алгоритмы для других языков с другими правилами произношения.
  • 8
    Хотя это правда, мы находимся в странной ситуации здесь. Основной запрос был «Я пытаюсь найти слово Gadaffi», но я чувствую, что регулярное выражение было красной сельдью. Не существует сборника правил транслитерации на арабский и латинский языки, и поэтому обращение к регулярному выражению из списка не будет полностью отвечать первоначальному запросу.
Показать ещё 2 комментария
27

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

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

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

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

  • 3
    Далее просто отправьте nytimes.com через Google Translate, и Боб станет вашим дядей.
19

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

  • 2
    Я знаю, что это возможно там, но как бы вы это сделали на практике (используя, например, какой-то общий динамический язык)
  • 3
    Я понимаю теорию, стоящую за этим, но, как и @Rory, мне также интересно узнать, как бы вы на самом деле сделали это на практике.
Показать ещё 2 комментария
10

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

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)

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

6

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

4

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

1

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

Ни одно из этих двух регулярных выражений не является самым красивым, но они оптимизированы и оба соответствуют 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

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

1

Почему бы не сделать смешанный подход? Что-то между списком всех возможностей и сложным 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

  • 0
    Ваши \b включены только в первый и последний варианты.
  • 0
    @ Кристофер Кройциг, конечно, вы правы, исправлено.
0

Что еще начинается с 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

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

  • 2
    Из крекинг словаря , который я случайно уже сидели: 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 . Однако некоторые из них не являются ложными срабатываниями.
  • 2
    И дополнения к этому списку, которые заканчиваются на [iy] вместо просто i : gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню