一部の正規表現エンジン (PCRE など) には、構文があり(?|...)
ます。これは非キャプチャ グループのようなものですが、すべての交互グループで同じ初期値からカウントされるという優れた機能があります。これはおそらくあなたの問題をすぐに解決するでしょう。したがって、このタスクの言語を切り替えるオプションがある場合は、それでうまくいくはずです.
[編集:実際には、名前付きキャプチャ グループの衝突で問題が発生します。実際、グループ名は再利用できないため、このパターンはコンパイルさえできません。]
そうしないと、入力パターンを操作する必要があります。hyde は後方参照の番号を付け直すことを提案しましたが、もっと簡単なオプションがあると思います: すべてのグループを名前付きグループにすることです。名前が一意であることを確認できます。
基本的に、入力パターンごとに一意の識別子を作成します (たとえば、ID をインクリメントします)。次に、最も難しい部分は、パターン内のキャプチャ グループを見つけることです。正規表現ではこれを行うことはできません。パターンを自分で解析する必要があります。パターン文字列を単純に繰り返し処理する場合に注意すべき点について、いくつかの考えを次に示します。
- 文字クラス内の括弧はリテラル文字であるため、文字クラスに出入りするときは注意してください。
?:
おそらく最もトリッキーな部分: , ?=
, ?!
, ?<=
,が続く開き括弧をすべて無視し?<!
ます?>
。さらに、オプション設定の括弧:(?idmsuxU-idmsuxU)
またはもあり、(?idmsux-idmsux:somePatternHere)
これも何もキャプチャしません (もちろん、これらのオプションのサブセットが存在する可能性があり、それらは任意の順序である可能性があり-
ます。これもオプションです)。
- これで、通常のキャプチャ グループまたは名前付き on: のいずれかである開き括弧のみが残るはずです
(?<name>
。最も簡単な方法は、それらをすべて同じように扱うことです。つまり、番号と名前の両方を持ちます (設定されていない場合、名前は番号と同じです)。次に、これらすべてを次のように書き換えます(?<uniqueIdentifier-md5hashOfName>
(ハイフンは実際には名前の一部にすることはできません。増分した数字の後にハッシュが続くだけです-ハッシュは固定長であるため、重複はありません;ほとんど少しでも)。グループが元々持っていた番号と名前を覚えておいてください。
- バックスラッシュに遭遇したときはいつでも、次の 3 つのオプションがあります。
- 次の文字は数字です。番号付き後方参照があります。これらすべての番号を、グループ用に生成した新しいグループ名の
k<name>
場所に置き換えます。name
- 次の文字は
k<...>
. これを再度、対応する新しい名前に置き換えます。
- 次の文字はその他です。スキップしてください。これは、括弧のエスケープとバックスラッシュのエスケープを同時に処理します。
- Javaは前方参照を許可するかもしれないと思います。その場合は、2 つのパスが必要です。最初にすべてのグループの名前を変更してください。次に、すべての参照を変更します。
すべての入力パターンでこれを実行したら、それらすべてを安全に結合できます|
。後方参照以外の機能は、このアプローチで問題を引き起こすことはありません。少なくとも、パターンが有効である限りは。もちろん、入力がa(b
ありc)d
、問題がある場合。しかし、パターンが独自にコンパイルできることを確認しないと、常にそれが発生します。
これが正しい方向への指針になったことを願っています。