まず、正規表現は xml の解析には適していないことを理解しています。代わりに xml パーサーを使用する必要があります。おそらく、私の質問は、これが真実である理由の良い例です。
そうは言っても、私がする必要があるのは、いくつかの XML ファイルを 1 回だけ検索して置換することだけです。さらに、私は正規表現に比較的慣れていないので、正規表現をよりよく理解し、XMLにとってなぜそれが悪い考えなのかを理解したいと思っています。
次の XML があります (元のファイルにはタグ間にスペースがありません!):
<tag1>
<tag2>Doesn't matter what is here</tag2>
</tag1>
<tag1>
<tag2>Anything can <b>go<b> here</tag2>
<tag3>Hi there</tag3>
</tag1>
tag3 内の「こんにちは」を 2 つの部分に分割する必要があります。これらは両方とも tag1 に囲まれ、存在する場合は同じ tag2 を持ちます。つまり、次のようになります。
<tag1>
<tag2>Doesn't matter what is here</tag2>
</tag1>
<tag1>
<tag2>Anything can <b>go<b> here</tag2>
<tag3>Hi</tag3>
</tag1>
<tag1>
<tag2>Anything can <b>go<b> here</tag2>
<tag3>there</tag3>
</tag1>
私の最初のアイデアは、次のように貪欲でない量指定子を持つ tag2 のオプションのグループを使用することでした:
<tag1>(<tag2>.*?</tag2>)?<tag3>Hi there</tag3></tag1>
(Java 構文) に置き換えます。
<tag1>$1<tag3>Hi</tag3></tag1><tag1>$1<tag3>there</tag3></tag1>
しかし 。*?まだ貪欲すぎます。tag1 の最初の開始から tag1 の最後の終了まで一致します。これを行う適切な正規表現の方法は何ですか? それとも、これは正規表現にとって難しい問題ですか? これが、XML に正規表現を使用することが非常に悪い考えである理由の 1 つですか?
アトミックグループを使用すると、まさに私が望むことができることがわかりました。
<tag1>(?>(<tag2>.*?</tag2>))?<tag3>Hi there</tag3></tag1>
しかし、なぜそうなのかはよくわかりません。なぜこれが機能し、これは十分に信頼できるのでしょうか?