クリーンアップ後、空のタグがたくさんできました。それらを削除したいのですが、これまで使用してきた表現は次のとおりです。
Regex.Replace(clean, "(<[/a-zA-Z]+?)([^>]*?)(>)", "$1$3");
ここで議論を見たことがありますが、明確にはなりませんでした。スラッシュを除いて、タグの最初と 2 番目に検出されたコンテンツが (それらを一致させるために) 同じであることを確認するにはどうすればよいですか?
後方参照を使用して、終了要素の名前が開始タグの名前と一致することを確認できます。これは、Konrad のソリューションを拡張して得たパターンです。
result = Regex.Replace(input, @"<([^>/][^>]*)></\1>", String.Empty);
ここで\1
は、パターン内で一致する最初のグループを参照します。これは、開始要素の名前を囲むパターン内の括弧で示されます。
同種かどうか調べる必要はないと思います。これは、有効な XML 構造があることを前提としています。もしそうなら、フォームには何もありません:
<someTagStarts></anOtherTagEnds>
したがって、次の正規表現を使用できます。
Regex.Replace(input, "<[^>/][^>]*></[^>]*>", "");
このリンクも見つけましたが、終了タグでスターの代わりにプラスを使用している理由がわかりません. それについて尋ねたほうがいいです。
一見空のタグ (空のスペースなどを含む) を削除する必要があるかもしれないことに気付き、Sina のソリューションを元に戻し、以下を追加できます)。
Regex.Replace(input, @"<([^>/][^>]*)>(( )*|\s*)</\1>", String.Empty);
正規表現のかわいい経験から厄介な経験に移行するのは、このあたりのどこかです。:)
これは遅い答えになりますが、前の質問で言ったように:
正規表現で xml/html を解析しようとしないでください。実際の xml パーサーを使用して xml を処理してください
ただし、いくつかの単純なケースでは機能する可能性がありますが、メンテナンスやコーナーケースの処理中にはより多くの問題が発生します.
var xml = @"<root>
<notempty>text</notempty>
<empty1><empty2><empty3/></empty2></empty1>
</root>";
var xDoc = XDocument.Parse(xml);
RemoveEmptyNodes(xDoc.Root);
xDoc.Save(fileName2);
void RemoveEmptyNodes(XElement xRoot)
{
foreach (var xElem in xRoot.Descendants().ToList())
{
RemoveEmptyNodes(xElem);
if (String.IsNullOrWhiteSpace((string)xElem) && xElem.Parent!=null)
xElem.Remove();
}
}
出力は次のようになります(@kirmirが言及したケースの処理)
<root>
<notempty>text</notempty>
</root>