0
"^(?:(2\d\d\d)\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+(\S+)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$"

現在、これは次のような文字列を解析できます

2009 IA H.B. 184 (NS)

次のようなテキストを解析するにはどうすればよいですか

2009 IA HEART RATE 184 (NS)

間隔のある単語 HEART RATE を解析できるようにする調整を探しています。

編集: 3 番目の単語が離れていない限り、機能するようです。たとえば、2009 IA REG 184 (NS) では機能しますが、3 番目の単語が実際にスペースで構成されるとすぐに、たとえば HEART RATE のようにうまくいきません。

4

2 に答える 2

0

HEART RATEスペースが見つかるまで読むだけで「3番目の単語」(2番目の正規表現キャプチャグループ)を読み取ろうとしているため、現在は機能しません。(2番目(\S+))。

これを修正するために、「3 番目の単語」は、数字または で始まる単語に到達するまで、スペースで区切られたすべての単語であると仮定しNo.ます(この仮定が間違っている場合は教えてください!)。これが((?:\S|\s(?!\d|No\.))+)解決策です。

これが私の解決策です:

"^(?:2\d{3}\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+((?:\S|\s(?!\d|No\.))+)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$"

私はそれをテストするとき

2009 IA HB 184 (NS)

それは(まだ)3番目の単語がH.B.

私はそれをテストするとき

2009 IA 心拍数 184 (NS)

3 番目の単語がHEART RATE

私はそれをテストするとき

2009 IA 心拍数 なし 184 (NS)

3 番目の単語がHEART RATE None

私はそれをテストするとき

2009 IA 心拍数 No. 184 (NS)

3 番目の単語がHEART RATE

いいね?

PS gskinerは素晴らしいです。

于 2012-08-09T23:08:05.103 に答える
0

式をその部分に分解してみましょう。

  1. ^
    行の先頭から開始します。

  2. (?:(2\d\d\d)\s+)?
    年が表示された場合は、グループ 1 でキャプチャします (グループ 0 がすべてです)。年号がなくても構いません。

  3. (?:Comm\. Rep\.\s+)?
    文字列「Comm. Rep.」を受け入れます。および 1 つ以上の空白文字を含みますが、キャプチャしません。なくても構いません。

  4. (?:CONG\s+)?
    文字列「CONG」と 1 つ以上の空白文字を受け入れますが、キャプチャしません。なくても構いません。

  5. (\S+)\s+(\S+)\s+
    それぞれに少なくとも 1 つの空白が続く、少なくとも 1 文字の長さの非空白文字の 2 つのブロックが存在する必要があります。グループ 2 と 3 のブロックをキャプチャします。

  6. (?:No\.\s+)?
    文字列「いいえ」を受け入れます。および 1 つ以上の空白文字を含みますが、キャプチャしません。なくても構いません。

  7. (\S+)
    少なくとも 1 つの非空白文字の別のブロックが存在する必要があります。グループ 4 でキャプチャします。

  8. (?:\s+\(.*?\))?
    括弧内にある限り、少なくとも 1 つの空白の後に何かが続くことを受け入れますが、それをキャプチャしないでください。なくても構いません。

  9. $
    次に、行を終了する必要があります。

パーツが現在の一致にどのようにマップされるかを次に示します (行頭と行末は省略します)。

2009 IA H.B. 184 (NS)
---- ------- --- ----
2    5       7   8

2 つの「ブロック」しか受け入れられないため、問題は式のパート 5 にあります。

2009 IA HEART RATE 184 (NS)
---- ------------- --- ----
2    ???           7   8

文字列「HEART RATE」も 3 番目のグループに入る必要があると仮定すると、5 番目の部分を次のように置き換える必要があります。

(\S+)\s+
少なくとも 1 つの空白以外の文字とそれに続く少なくとも 1 つの空白のブロックを受け入れ、それをグループ 2 (変更なし) でキャプチャします。

(.+?)\s+
グループ 3 の最後の空白を除くすべての空白をキャプチャします。

したがって、全体として必要な式は次のとおりです。

^(?:(2\d\d\d)\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+(.+?)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$

ところで、私はhttp://regexpal.comにとても満足しています。

PS: Carl Walsh のソリューションは、貪欲でない (または怠惰な) キャプチャに依存しないため、パフォーマンスに関しては少しスマートです。

于 2012-08-09T23:46:04.850 に答える