Регулярний вираз для пошуку Gadaffi


361

Я намагаюся шукати слово 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
Кадафі
Gadafy
Каддафі
Кадафі
Каддафі
Каддафі
Гатафі
Ґадаффі
Кадафі
Каддафі
Ґаддафі
Геддафі
Кадаффі
Кадафі
Каддафі
Каддафі
Каззафі
Хадаффі
Хадафі
Каддафі
Кадафі
Каддафі
Каддафі
Каддафі
Кадтафі
Катафафі
Кватфафі
Куддафі
Кадфафі

8
Яких вам не вистачає? А де ви шукаєте, чи є веб-пошук з регексом?
Чехологія

43
Завжди публікуються нові журнали, тому якщо вони продовжують писати про Gadaffi, ви будете схильні .+бути єдиним правильним регулярним виразом.
moinudin

30
Я виявив, що ця картина допомагає в різних написаннях: upload.wikimedia.org/math/6/1/f/…
KLee1

24
Як завжди, Лісп реалізував це першим - foldr.org/~michaelw/projects/regex/regexp-test-suite.lisp (прокручуйте півдороги вниз)
Даніель С. Стерлінг

7
@ Даніель Стерлінг: насправді тест Khadafy є частиною грейп-тесту GNU з початкової передачі RCS (вт. 3 листопада 21:38:52 1998 +0000) і, ймовірно, навіть старший за це!
Паоло Бонзіні

Відповіді:


138

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

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

До речі, чому є $кінець регулярного вираження?


Btw, приємна стаття на тему:

Кадафі, Кадафі чи Каддафі? Чому ім'я лівійського лідера написано так багато різних способів? .


EDIT

Щоб відповідати всім іменам у статті, яку ви згадували пізніше , це має відповідати всім. Будемо просто сподіватися, що він не збігається з багатьма іншими речами: D

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

$ Помиляється, я спочатку підрівнював кінець рядків, забув видалити його.
SiggyF

Чи dвідповідає також ḏ?
SiggyF

2
@DiggyF, ні, я просто подумав, що якщо арабська транскрипція говорить Qaḏḏāfī, то регулярний вигляд повинен також перевірити Qaddafi. Якщо ви також хочете шукати арабську транскрипцію, просто шукайте її - я не думаю, що існує більше варіантів арабської транскрипції, лише англійська транскрипція.
Czechnology

@DiggyF, я відредагував довший регулярний вираз, який відповідає всім назвам статті, яку ви опублікували (крім двох, ?а не літер). Хоча це може бути зайвим.
Czechnology

2
Це також відповідає "Quuzzafi" та купі інших помилкових позитивних результатів, хоча я припускаю, що в пошуку репортажів новин тощо, що не буде багато значення.
ben w

275

Легко ... (Qadaffi|Khadafy|Qadafi|... )... це самодокументоване, реконструйоване, і якщо припустити, що ваш двигун regexp насправді збирає регулярні вирази (а не інтерпретувати їх), він буде компілюватися в той самий DFA, що і більш заплутане рішення.

Написати компактні регулярні вирази - це як використовувати короткі імена змінних для прискорення програми. Це допомагає лише якщо ваш компілятор загинув від мозку.


23
Чудова відповідь! Люди використовують регулярні вирази набагато частіше, ніж їх хвилює те, як вони насправді працюють.
Томас Ейл

3
Мені дуже подобається простота цього рішення, але я здивований, що це буде збігатися до тієї самої DFA. Чи є у вас посилання, що говорить про це? Інтуїтивно це здається, що це може бути менш ефективним, ніж раніше створений регулярний вираз або відповідь нижче, що пропонує використовувати модуль Regexp :: Aslect perl у тому самому списку імен or'd.
Rian Sanderson,

6
-1 Вся суть регексу полягає в тому, щоб скоротити те, що часто може бути - як це в цьому випадку - дуже довгим переліком альтернатив порівняно короткої формули. Результат часто може виконуватись швидше, ніж робити те, що по суті є неоптимізованим вичерпним пошуком.
мартіно

7
Ви маєте рацію, що точкою регулярних виразів є створення компактного, чіткого подання для великого набору значень. Але основна концепція полягає в тому, щоб представити регулярний вираз і сказати "все, що відповідає цьому, добре". Тобто передбачається, що ви маєте свободу включати що-небудь систематичне. Тут ми маємо протилежну ситуацію: варіанти написання (і варіації, які ніколи не з'являються) є лише ледь цією стороною "абсолютно випадкових". Ретельні спроби "компактного" отримують дуже низькі бали за "ясні"!
jackr

1
Також ознайомтеся з алгоритмом Aho-Corasick, який є оптимальним для одночасного пошуку рядків: en.wikipedia.org/wiki/…
Thomas Ahle

45

Одне цікаве, що слід відзначити у вашому списку потенційних написань, - це те, що у вміщеному списку є лише 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", але я відчуваю, що регулярний вираз був червоною оселедцем. Немає правила щодо транслітерації з арабської мови на латинську мову, і як таке повернення регулярного виразу зі списку не повністю відповідає оригінальному запиту.
tomwalsham

2
Я вважаю, що система нечіткої відповідності краще підходить, але користувацький алгоритм здається непосильним. Використання комбінації звукових файлів-метафонів, схоже, є ефективною, а також рішенням регулярного виразів, що дозволяє подальше непередбачуване написання, використовуючи ще й нестандартні символи.
tomwalsham

Використання metaphone2 та metaphone3 призводить до кращих результатів (тобто майже все в метафоні2 - це KDF, де як метафон1 не зовсім). Метафон3, однак, коштує близько 40 баксів.
інкогніто

27

Використання модуля CPAN Regexp :: Зберіть :

#!/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
Я знаю, що це можливо з теоретичної точки зору, але як би ви це зробили на практиці (використовуючи, наприклад, сому загальну динамічну мову)
Rory

3
Я розумію теорію, що стоїть за цим, але, як і @ Rory, мені також цікаво знати, як ви насправді це зробили на практиці.
dancavallaro

так, я думав про це, щоб дати кращу відповідь, але на даний момент я трохи зайнятий. у мене є деякий (потворний і погано задокументований) код на code.google.com/p/lepl/source/browse/src/lepl/regexp/core.py, який створює dfa з regexp (насправді парсер знаходиться в іншому класі , але важка робота там є, ви йдете regexp -> nfa -> dfa). перейти від dfa до regexp легко (я думаю?).
andrew cooke

насправді документація там краща, ніж я пам’ятаю: o) основна ідея полягає в тому, що ви описуєте регулярне вираження з точки зору класів у верхній частині файлу. що потім можна легко перекласти на nfa (nfa насправді просто набір переходів, що говорить "якщо ти отримаєш цей лист, то можеш перейти сюди чи сюди ...", це досить легко зрозуміти). dfa - це свого роду "розширена" версія тієї версії, де вам не доводиться повторювати; це робиться NfaToDfa (і це складна частина). Тоді dfa може бути, як, наприклад, самим повторним формуванням, записаним як дуже складний набір символів (?!)
andrew cooke

10

Якщо у вас є конкретний перелік усіх 30 можливостей, просто об'єднайте їх разом з купою "ors". Тоді ви можете бути впевнені, що він відповідає лише тим, що ви перерахували, і не більше. Ваш RE двигун, ймовірно, зможе оптимізуватись у подальшому, і, ну, з 30 варіантів, навіть якщо це не так, все одно це не велика справа. Намагаючись зіграти навколо, вручну перетворивши його на «розумний» РЕ, можливо, не вийде краще і може вийти гіршим.


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)

Безумовно, не найоптимізованіша версія, розділіть на склади для максимального збігу, намагаючись переконатися, що ми не отримаємо помилкових позитивних результатів.


7

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



1

Чому б не зробити змішаний підхід? Щось між переліком усіх можливостей та складним Regex, що відповідає занадто багато.

Regex стосується відповідності шаблонів, і я не можу побачити шаблон для всіх варіантів у списку. Намагаючись це зробити, ви також знайдете такі речі, як "Gazzafy" або "Quud'haffi", які, швидше за все, не є вживаним варіантом і, безумовно, відсутні у списку.

Але я бачу візерунки для деяких варіантів, і тому я закінчив це:

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

На початку я перераховую ті, де я не бачу візерунка, а потім слідують деякі варіанти, де є шаблони.

Дивіться це тут на www.rubular.com


Ви \bтільки включені в першому і останньому альтернативі.
Крістофер Кройціг

1

Я знаю, що це старе питання, але ...

Жоден із цих двох регексів не є найкрасивішим, але вони оптимізовані і обидва відповідають ВСІМ варіаціям у початковій публікації.

"Маленька красуня" №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

Спочивай у мирі, Муаммар.


0

Просто додаток: ви повинні додати "Геддафі" як альтернативне написання. Тож РЕ має бути

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

0

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

Частинами:

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

Примітка. Просто хотілося зняти це.


-1

Що ще починається з Q, G або K, має рекламу, 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 . Деякі з них не є помилковими , але.
BMDan

2
І доповнення до цього списку, які закінчуються [iy]замість просто i:gelatinify gentrify ghostlify giddify gladify goutify gratify "Gyula Dessewffy" katasrofy katastrofy khadafy quantify quasi-deify quizzify
BMDan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.