ホームページ >Java >&#&チュートリアル >再帰やグループのバランスをとらずに入れ子になった括弧を一致させる方法は?

再帰やグループのバランスをとらずに入れ子になった括弧を一致させる方法は?

DDD
DDDオリジナル
2024-10-25 02:35:02471ブラウズ

How to Match Nested Brackets Without Recursion or Balancing Groups?

再帰またはバランシンググループを使用せずに入れ子になった括弧を照合する

課題:

一連の要素を照合するJava の java.util.regex など、再帰とバランシング グループ サポートのない正規表現を使用して任意にネストされた括弧を使用し、指定された文字列内の 3 つの外側のグループをキャプチャします:

(F(i(r(s)t))) ((S)(e)((c)(o))(n)d) (((((((Third)))))))

解決策: Forward References to the Rescue

一般に信じられていることに反して、これらの高度な機能を使用せずにネストされた括弧を一致させることは、前方参照を使用して可能です:

(?=\()(?:(?=.*?\((?!.*?)(.*\)(?!.*).*))(?=.*?\)(?!.*?)(.*)).)+?.*?(?=)[^(]*(?=$)

Break it Down:

この複雑な正規表現は 2 つのステージで動作します:

  • ステージ 1: 先読みは、文字を消費せずにバランスの取れた括弧のシーケンスを識別します。このプロセスは、完全な外部グループが見つかるまで続行されます。
  • ステージ 2: キャプチャ グループは、一致した外部グループの内容を抽出します。

仕組み:

  • '(' のチェック: '(' が見つかるまで文字列を進めます。
  • マッチングバランスの取れた括弧: 2 つの先読みを使用して、次の '(' と ')' がバランスの取れた方法で一致していることを確認し、内部の内容をキャプチャします。
  • 閉じ括弧のチェック: をチェックします。前に一致した '(' と一致する終了 ')' を選択し、さらに進みます。
  • End-of-Outer-Group Check: 終了 ' の前に '(' が出現しないようにします。

内部グループのマッチング バリアント:

内部グループのマッチングでは、戦略は同じですが、キャプチャ グループが使用されます。一致したコンテンツを括弧のバランスのとれたペア内に保存します:

(?=\()(?=((?:(?=.*?\((?!.*?)(.*\)(?!.*).*))(?=.*?\)(?!.*?)(.*)).)+?.*?(?=)[^(]*(?=$))) 

包括的な分割:

正規表現のコンポーネントと機能をまとめた表:

Note Component Description
(?=() Look for '('
(?: Start group for iteration
(?=.?((?!.?1)) Look for '(' not followed by 1, which contains the matched inner content
(.)(?!.2).*)) Capture inner content and check for at least one more ')'
(?=.?)(?!.?3)) Look for ')' not followed by 2, which contains the matched outer content
(. ) Capture outer content
. Consume a character
) Close group
? Match as few times as possible
.*?(?=1) Match up to and including the last '('
1*(?=2$) Match up to the last ')' without encountering more '('

  1. (

以上が再帰やグループのバランスをとらずに入れ子になった括弧を一致させる方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。