0

一般に、この問題に対する一般的な解決策に出くわしたとは思いません。範囲または単一の値である可能性がある文字列をどのように照合しますか?

[複雑な] 日付に一致させたいとします。

  • 1999 - 2010
  • 紀元前323年~紀元100年
  • 紀元前323年
  • 1995-99
  • 紀元前323年 - 紀元前322年

これらの両方のケースを解析できる一般的な正規表現「テンプレート」は何ですか:

  1. 存在する場合は開始日/終了日
  2. それ以外の場合は、単一の日付のみ

「1999 - 2010」に一致させるには、次のようにします

/(\d+\s*)-(\s*\d+)/ // where $1 and $2 are start and end

より複雑な「紀元前 323 年 - 紀元 100 年」に合わせるには、次のようにします。

/(\w+\s*\w+)\s*-\s*(\w+\s*\w+)/

そして、より単純な「323 BC」に合わせて、次のことができます

/\w+\s*\w+/

しかし、最初に範囲(323 BCE - 100 CE) をチェックし、それが存在しない場合は単一の値 (323 BC) をチェックし、上記のリストの他の例も処理できる1 つの式をどのように記述しますか? ?

4

3 に答える 3

2

マッチの後半部分をオプションにすることで。

/(\w+\s*\w+)(?:\s*-\s*(\w+\s*\w+))?/

(JavaScript)

"1900 - 2000".match(/(\w+\s*\w+)(?:\s*-\s*(\w+\s*\w+))?/);
//["1900 - 2000", "1900", "2000"]

"1900 BC".match(/(\w+\s*\w+)(?:\s*-\s*(\w+\s*\w+))?/);
//["1900 BC", "1900 BC", undefined]

外側のオプション部分は一致しないように作成されているため、結果の配列には関心のあるサブマッチのみが含まれていることに注意してください。

また、効率的にパターンを強化することも考えられます。たとえば、英数字ではなく数字を探し、ゼロ以上ではなく単一のスペース (これが許容される場合) のみを許可します。

于 2012-06-23T09:43:43.997 に答える
0

あなたが望むように機能する可能性のある別のパターンを投入するだけです。

((\d+)( [A-Za-z]+|))((-| - )\d+( [A-Za-z]+|)|)

そして、ウトカノスのパターンと同様に、これは他のものと一致しないようにいくらか引き締める必要があるかもしれません.

于 2012-06-23T09:48:34.477 に答える
0

あなたはおそらく次のようなものを探しています:

var pattern = /(\d+)(\s*(\w+))?(\s*-\s*(\d+)(\s*(\w+))?)?/;
var strings = [
    '1999 - 2010',
    '323 BCE - 100 CE',
    '323 BC',
    '1995-99',
    '323 - 322 BC'
];

for (var i=0, s; s = strings[i]; i++) {
    var m  = s.match(pattern);
    console.log(
        m[1], // beginning year
        m[3], // beginning b/c/e
        m[5], // end year
        m[7]  // end b/c/e
    );
}

出力する

1999  undefined  2010       undefined
323   BCE        100        CE
323   BC         undefined  undefined
1995  undefined  99         undefined
323   undefined  322        BC

ここでの秘訣は、それ(group)?(group)オプションであることを理解することです。(foo)+これと同様に(foo){3}、グループを少なくとも 1 回または正確に 3 回一致させるために使用できます。

(foo)デフォルトでは、グループはキャプチャ グループです。つまり、結果は String#match() によって返される配列に含まれます。次のように、グループを非キャプチャとしてマークできます(?:wont-be-captured)。これにより、上記のパターンをさらに変更できます。

var pattern = /(\d+)(?:\s*(\w+))?(?:\s*-\s*(\d+)(?:\s*(\w+))?)?/;
for (var i=0, s; s = strings[i]; i++) {
    var m  = s.match(pattern);
    console.log(m[1], m[2], m[3], m[4]);
}
于 2012-06-23T10:39:12.120 に答える