5

これは私がこれまでに持っているものです...

var regex_string = "s(at)?u(?(1)r|n)day"
console.log("Before: "+regex_string)
var regex_string = regex_string.replace(/\(\?\((\d)\)(.+?\|)(.+?)\)/g,'((?!\\$1)$2\\$1$3)')
console.log("After: "+regex_string)
var rex = new RegExp(regex_string)

var arr = "thursday tuesday thuesday tursday saturday sunday surday satunday monday".split(" ")
for(i in arr){
  var m
  if(m = arr[i].match(rex)){
    console.log(m[0])
  }
}

は数字で、は(?(n)a|b)文字((?!\n)a|\nb)列です。これは問題なく機能しているようですが、これは大きなファットハックであることを認識しています。nab

この問題に取り組むためのより良い方法はありますか?

4

1 に答える 1

14

正規表現の特定のケースでは、交互に使用する方がはるかに簡単で読みやすくなります。

(?:sunday|saturday)

または、条件付き正規表現が関係する2つの位置の間でのみ交互を作成できます(これは、そのような条件式が多数あるが、近くのキャプチャグループのみを参照する場合に便利です)。例としてあなたのケースを使用して、条件に関係しているのはそれらだけであるため、私たちは交代を作成するだけunですatur

s(?:un|atur)day

条件付き正規表現には2つの一般的なタイプがあります。(Perl正規表現でサポートされているエキゾチックなものは他にもありますが、JavaScript正規表現やその他の一般的な正規表現エンジンにはない機能のサポートが必要です)。

  1. 最初のタイプは、明示的なパターンが条件として提供される場合です。このタイプは、JavaScript正規表現で模倣できます。条件付き正規表現をサポートする言語では、パターンは次のようになります。

    (?(conditional-pattern)yes-pattern|no-pattern)
    

    conditional-patternJavaScriptでは、オリジナルが先読みであるという(明らかな)仮定で、先読みでそれを模倣できます。

    ((?=conditional-pattern)yes-pattern|(?!conditional-pattern)no-pattern)
    

    conditional-pattern入力文字列がを通過して失敗する場合を防ぐために、負の先読みが必要ですが、yes-patternは一致する可能性がありno-patternます。ポジティブルックアラウンドとネガティブルックアラウンドは論理的に正反対であるため、これを行うのは安全です。

  2. 2番目のタイプは、キャプチャーグループへの参照(名前または番号)が提供される場合であり、キャプチャーグループが一致すると条件がtrueと評価されます。このような場合、簡単な解決策はありません。

    私が考えることができる唯一の方法は、例としてあなたのケースで私がしたことのように、複製によるものです。もちろん、これは保守性を低下させます。source正規表現を部分的に(リテラルRegExpで)記述​​し、属性を使用して文字列を取得し、それらを連結することで、正規表現を作成することができます。これにより、変更を他の複製された部分に伝播できますが、正規表現を理解したり、大幅な変更を加えたりすることが難しくなります。

参考文献

于 2013-02-22T14:14:43.907 に答える