2

Perlで正規表現を一致させるのに問題があり、誰かが何か洞察を持っているかどうか疑問に思っていました:

これが私の正規表現です:/^-MEMBER:\s+(\b[^,]+)(?:,\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/

これが私が一致しているものです:

-メンバー:Doe、John H ID#:3907

正規表現は美しく機能し、上記の行と一致しますが、名とミドルが含まれていない可能性のある行で問題が発生しています。以下の例:

-メンバー:Doe、ID#:3907

両方の行の現在の正規表現との一致に問題があります。

助けてくれてありがとう!

4

3 に答える 3

1

オプションの名グループ内にコンマ一致を配置したため、名が存在する場合にのみコンマを一致させることができます。名のない名前にコンマを付ける場合は、名前グループに移動する必要があります。

/^-MEMBER:\s+(\b[^,]+,)(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/
于 2013-03-14T17:49:48.430 に答える
0

この正規表現は両方の行に一致します:

/
    ^-MEMBER:\s+         # the beginning of the line with "-MEMBER: "
    .*?                  # non greedy
    \s+ID#:\s+(\d+)$     # space and end ID part
/x
于 2013-03-14T17:39:41.573 に答える
0

問題は、あなたが実際にあなたの入力を説明する文法とは何かということです。すべてを一度に説明しようとすると、非常に複雑になり、非常に速くなります。別の方法については、 perlyappモジュールを参照してください。

ただし、正規表現のみを使用することを主張する場合は、次のようにします。

/^-MEMBER: # start of line, match specific string
\s+ # must be followed by at least one whitespace char
(\b[^,]+) # now we need to match a word in a capture group
(?:,\s(\b.{1,50}\b)\.?)? # here's the pain, so lets deal with it below
\s+ # more whitespace
ID#: # match this string
\s+ # and some more whitespace
(\d+)$/ # digits at the end of the line

(
 ?: # cluster the following
 ,\s # comma, then a single space
 (
  \b.{1,50}\b # up to fifty "things" bounded by words
 ) # another capture group
 \.? # optional period
)? # zero or one of these I.E. optional capture

これは、仮定を「言語」にハードコード化するため、fragilです。ファーストネーム/ミ​​ドルネームがない場合、オプションのグループ内にあるため、コンマは許可されないことに注意してください。これが、2番目のテストが一致しないという問題です。

次に、ファーストネーム/ミ​​ドルネームのセクションがある場合は、改行以外のものを含めることができます。これはあなたが望むまたは期待するものではないかもしれません。

パーサーが有用である理由は、パーサーが「コンテキスト」を持つことを可能にするからではありませんが、それは可能です。これは、複雑な正規表現を、明確に定義された全体に接続された、小さくて管理しやすい部分に分割するためです。そのようなツールを学ぶことによって、あなたがここで抱えている問題のタイプは、実装し、変更するのが簡単になります。

正規表現が各セクションで「有効」なものを定義しようとしていることに注目してください。姓(\b[^,]+)にはコンマ以外の名前を付けることができます。これは、あなたの望むことですか?有効な名前だけを含めることができる場合はどう[a-zA-Z_]なりますか?;injectionattemptFTW!!;#有効な名前ですか?限られた明白な条件のセットが存在するようにプログラムを設計します。If a then valid, else fail単純なsについて推論するのは簡単aです。

考えられるすべての特殊なケースを定義しない限り、この正規表現を壊すような事態に遭遇します。完全な正規表現を定義できないため、2つのオプションがあります。

  1. 特殊なケースが特定されると、正規表現をさらに複雑にパッチします
  2. 複雑な正規表現の必要性を回避するための再設計

オプション1を選択した場合、この正規表現は現在の問題を修正します。

/^-MEMBER:\s+(\b[^,]+),?(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/
于 2013-03-14T17:58:13.443 に答える