4

私は正規表現にかなりの経験がありますが、論理和を含む現在のアプリケーションでは問題があります。

私の状況は次のとおりです。アドレスの「識別子要素」の正規表現の一致に基づいて、アドレスを構成要素に分離する必要があります。同等の英語の例は、「state」、「road」、「 boulevard」-たとえば、これらを住所に書き留めた場合。次のようなアドレスがあるとします。ここで(これは英語では発生しません)、各名前の後に識別子の種類を指定しました

United States COUNTRY California STATE San Francisco CITY Mission STREET 345 NUMBER

(CAPSの単語は私が「識別子」と呼んでいるものです)。

これを次のように解析します。
United States COUNTRY
California STATE
San Francisco CITY
Mission STREET
245 NUMBER

OK、これは確かに英語のために考案されたものですが、ここに問題があります。私は中国語のデータを扱っています。実際、このスタイルの識別子の指定は常に行われています。以下の例:

云南-省 ; 丽江-市 ; 古城-区 ; 西安-街 ; 杨春-巷 ; Yunnan-Province ; LiJiang-City ; GuCheng-District ; Xi'An-Street ; Yangchun-Alley

これは非常に簡単です。論理和リストに分けられた、潜在的な候補識別子名の怠惰な一致です。

中国の場合、以下は「州レベル」のエンティティです。

省 (Province) , 自治区 (Autonomous Region) , 市 (Municipality)

したがって、これまでの私の正規表現は次のようになります。

(.+?(?:(?:省)|(?:自治区)|(?:市)))

アドレスのさまざまな部分を説明するために、これらのシリーズがあります。たとえば、都市に対応する次のレベルは次のとおりです。

(.+?(?:(?:地区)|(?:自治州)|(?:市)|(?:盟)))

したがって、州のエンティティとそれに続く都市のエンティティを一致させるには、次のようにします。

(.+?(?:(?:省)|(?:自治区)|(?:市)))(.+?(?:(?:地区)|(?:自治州)|(?:市)|(?:盟)))

名前付きキャプチャグループの場合:
(?<Province>.+?(?:(?:省)|(?:自治区)|(?:市)))(?<City>.+?(?:(?:地区)|(?:自治州)|(?:市)|(?:盟)))

上記の場合、これにより次のようになります。
$+{Province} = 云南省<br> $+{City} = 丽江市

これはすべてうまくいっていて、私をかなり遠ざけます。ただし、問題は、他の識別子のサブストリングである可能性のある識別子を考慮しようとする場合です。たとえば、一般的なストリートレベルのエンティティは、村民委員会を意味する「村民委員会」です。分離したいアドレスのセットでは、すべてのアドレスにこれが完全に書き出されているわけではありません。実は、私は「村団」と単なる「村」も見つけました。

問題?これらの要素の純粋な論理和がある場合、次のようになります。

(?<Street>.+?(?:(?:村委会)|(?:村委)|(?:村)))

しかし、何が起こるかというと、保定村委員会(Baoding Village組織委員会)のエンティティがある場合、この怠惰な正規表現は村に立ち寄り、それを1日と呼び、村は潜在的な分離要素の1つであるため、貧しい集会を孤立させます。 。

次のような英語の同等物を想像してみてください。
(?<Animal>.+?(?:(?:Cat)|(?:Elephant)|(?:CatElephant)|(?:City)))

2つの入力文字列があります
。1。「Crapcatelephant」と「crapcity」が必要な「crapcatelephantcrapcity」2。「crapcat」「elephantcity」が必要な「crapcatelephantcity」

ああ、あなたが言う解決策は、事前識別子のキャプチャを貪欲にすることです。だが!同じレベルではない同じ識別子を持つエンティティがあります。

市を例にとってみましょう。それは単に「都市」を意味します。しかし、中国には、郡レベル、州レベル、および市町村レベルの都市があります。この文字が文字列内で2回発生した場合、特に2つの隣接するエンティティで発生した場合、欲張り検索では、欲張り一致が最初のエンティティとして誤ってタグ付けされます。次のように:

广东-省 ; 江门-市 ; 开平-市 ; 三埠-区 石海管-区<br> Guangdong-province ; Jiangmen-City ; Kaiping-City ; Sanbu-District ; Shihaiguan-District

(上記のように、これは手動でセグメント化されていることに注意してください。生データには、連結された文字の文字列が含まれるだけです)

欲張り検索の一致は次のようになります
江门市开平市

これは間違っています。2つの隣接するエンティティを構成要素に分離する必要があるためです。かつては地方都市のレベルにあり、1つは郡レベルの都市です。

元のポイントに戻り、ここまで読んでいただきありがとうございます。分離エンティティに重みを付ける方法はありますか?正規表現で最も高い「重み付けされた」識別子を最初に見つけたいと思います。単純な村の代わりに村民委員会。たとえば、「猫」の代わりに「catelephant」。予備実験では、正規表現パーサーは、分離一致を見つける際に左から右に進んでいるようです。これは有効な仮定ですか?最も頻繁に発生する識別子を選言リストの最初に配置する必要がありますか?

中国語関連の詳細を持っている人を失った場合は、お詫び申し上げます。必要に応じてさらに明確にすることができます。例は実際には中国語である必要はありません。より一般的には、正規表現の選言的一致の仕組みに関する質問だと思います。どのような順序で選言的エンティティを優先し、いつ「呼び出す」かをどのように決定しますか。怠惰な検索のコンテキストで1日」?

ある意味で、怠惰な検索と貪欲な検索の間には、ある種の中間点がありますか?最長/最高加重の分離エンティティの前に見つけることができる最小のビットを見つけますか?怠惰になりますが、徹底するためにできれば、少し余分な努力をしますか?(ちなみに、大学での私の仕事の哲学は?)

4

1 に答える 1

8

How alternations are handled depends on the particular regular expression engine. For almost all engines (including Perl's regular expression engine) the alternation matches eagerly - that is, it matches the left-most choice first and only tries another alternative if this fails. For example, if you have /(cat|catelephant)/ it will never match catelephant. The solution is to reorder the choices so that the most specific comes first.

于 2011-01-28T20:12:24.427 に答える