Word 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 Qadhfi Qadhdhafi Qadthafi Qathafi Quathafi Qudhafi Kad'afi
\b[KGQ]h?add?h?af?fi\b
アラビア語の転写は(Wikiによれば) "Qaḏḏāfī"であるため、Qを追加することができます。また、1つのH(記事(以下を参照)が言及するように "Gadhafi")を追加します。
ところで、なぜ正規表現の最後に$
があるのですか?
ところで、このトピックに関する素敵な記事:
カダフィ、カダフィ、またはカダフィ。リビアの指導者の名前の綴り方が異なるのはなぜですか? 。
編集
後で説明した記事 のすべての名前を一致させるには、すべて一致する必要があります。それが他の多くのものと一致しないことを願っています:D
\b(Kh?|Gh?|Qu?)[aeu](d['dt]?|t|zz|dhd)h?aff?[iy]\b
簡単... (Qadaffi|Khadafy|Qadafi|
...)
...それは自己文書化されており、保守可能で、正規表現エンジンが正規表現を(それらを解釈するのではなく)実際にコンパイルすると仮定すると、より難読化されたソリューションと同じDFAにコンパイルされます。
コンパクトな正規表現の作成は、短い変数名を使用してプログラムを高速化するようなものです。コンパイラーが頭がおかしい場合にのみ役立ちます。
潜在的なスペルのリストから注意すべき興味深い点の1つは、含まれているリストのSoundex値が3つしかないことです(外れ値「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;
?>
いくつかの微調整を行い、キリル文字の音訳を行うと、かなり堅牢なソリューションが得られます。
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))
ここで物事を複雑にしていると思います。正しい正規表現は次のように簡単です:
\u0627\u0644\u0642\u0630\u0627\u0641\u064a
これは、Wordالقذافي(つまりGadaffi)を形成する7つのアラビア語Unicodeコードポイントの連結と一致します。
誰も使用していないものと一致することを避けたい場合(つまり、「。+」への傾向を避けたい場合)、最善のアプローチは、すべての選択肢である正規表現を作成することです(例(Qadafi | Kadafi | ...) )それをDFAにコンパイルし、DFAを正規表現に変換します。予想外のバリアントが含まれないことが保証されている「圧縮された」正規表現を提供する、適度に賢明な実装を想定します。
30の可能性すべての具体的なリストがある場合は、それらをすべて「or」の束で連結します。次に、sureになります。これは、リストしたものだけに一致し、それ以上は一致しません。あなたのREエンジンはおそらくさらに最適化することができるでしょう。そして、たとえそれがまだ大したことではないとしても、30の選択肢があります。手動でそれを「賢い」REに変えることでいじくり回そうとすることは、おそらく良くなることはできず、悪くなるかもしれません。
(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)
間違いなく最も最適化されたバージョンではなく、音節で分割して一致を最大化すると同時に、誤検出が発生しないようにします。
さて、小さな単語と一致しているので、 Levenshtein 距離で 類似性検索エンジン を試してみませんか?最大でkの挿入または削除を許可できます。このようにして、距離関数を特定の問題に適した他のものに変更できます。 simMetricsライブラリには多くの機能があります。
可能な代替案は、例から正規表現を生成するためのオンラインツールです http://regex.inginf.units.it 。チャンスをください!
なぜ混合アプローチをしないのですか?すべての可能性のリストと、あまりにも多く一致する複雑な正規表現の間の何か。
正規表現はパターンマッチングに関するものであり、リスト内のすべてのバリアントのパターンは表示されません。そうしようとすると、「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
これは古い質問ですが、...
これら2つの正規表現はどちらも最も美しいものではありませんが、最適化されており、両方とも元の投稿のバリエーションと一致します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
安らかに眠れ、ムアマル。
補遺:代替スペルとして「Gheddafi」を追加する必要があります。したがって、REは
\b[KG]h?[ae]dd?af?fi$\b
Q、G、またはKで始まり、d、z、またはtが中央にあり、「fi」で終わる人々実際 search?
/\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
おもしろいことに、私は落胆している。誰かがコメントに誤検知を残すことはできますか?
[GQK] [ahu] + [dtez] +\'?[adhz] + f {1,2}(i | y)
部分的に:
注:正規表現を習得し、試してみたかっただけです。後で小さな間違いを修正します