1

私が考えている関数は正規表現を使用することを想像しており<p><strong></strong></p>、文字列内のすべての空のHTMLタグを削除するようなインスタンスでは再帰的になります。これは、可能であれば空白を考慮に入れる必要があります。<文字が属性値で使用されていたというクレイジーな例はありません。

私は正規表現でかなりひどいですが、これは可能だと思います。どうすればいいですか?

これが私がこれまでに持っている方法です:

Public Shared Function stripEmptyHtmlTags(ByVal html As String) As String
    Dim newHtml As String = Regex.Replace(html, "/(<.+?>\s*</.+?>)/Usi", "")

    If html <> newHtml Then
        newHtml = stripEmptyHtmlTags(newHtml)
    End If

    Return newHtml
End Function

ただし、現在の正規表現はPHP形式であり、機能していないようです。.NET正規表現の構文に精通していません。

正規表現を使用しないでくださいと言っているすべての人に:私はパターンが関係なくどうなるか興味があります。確かに、すべての開始/終了開始タグをタグの間に任意の量の空白(またはなし)で一致させることができるパターンがありますか?<p></p>HTMLタグを任意の数の属性、1つの空のタグ(ちょうどなど)などと一致させる正規表現を見てきました。

これまでのところ、上記の方法で次の正規表現パターンを試しましたが、役に立ちませんでした(たとえば、空の段落タグが削除されていないテキスト文字列があります)。

Regex.Replace(html, "/(<.+?>\s*</.+?>)/Usi", "")

Regex.Replace(html, "(<.+?>\s*</.+?>)", "")

Regex.Replace(html, "%<(\w+)\b[^>]*>\s*</\1\s*>%", "")

Regex.Replace(html, "<\w+\s*>\s*</\1\s*>", "")

4

4 に答える 4

8

まず、空の HTML 要素は定義上、ネストされていないことに注意してください。

更新:以下のソリューションでは、空の要素の正規表現を再帰的に適用して、次のような「ネストされた空の要素」構造を削除します<p><strong></strong></p>(以下の注意事項に従います)。

シンプルバージョン:

<>これは、(テストされていない) VB.NET スニペットの形式で、面白いものを含む開始タグ属性を持たない HTML に対して非常にうまく機能します (以下の警告を参照) 。

Dim RegexObj As New Regex("<(\w+)\b[^>]*>\s*</\1\s*>")
Do While RegexObj.IsMatch(html)
    html = RegexObj.Replace(html, "")
Loop

強化版

<(\w+)\b(?:\s+[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[\w\-.:]+))?)*\s*/?>\s*</\1\s*>

VB.NET のコメントなしの拡張バージョン (未テスト) は次のとおりです。

Dim RegexObj As New Regex("<(\w+)\b(?:\s+[\w\-.:]+(?:\s*=\s*(?:""[^""]*""|'[^']*'|[\w\-.:]+))?)*\s*/?>\s*</\1\s*>")
Do While RegexObj.IsMatch(html)
    html = RegexObj.Replace(html, "")
Loop

このより複雑な正規表現は、属性値に山かっこが含まれている場合でも、有効な空の HTML 4.01 要素に正しく一致します(もう一度、以下の注意事項に従ってください)。<>つまり、この正規表現は、引用符で囲まれた ( を含むことができる)、引用符で囲まれていない (できない) および空のすべての開始タグ属性値を正しく処理します。以下は、完全にコメント済み (およびテスト済み) の PHP バージョンです。

function strip_empty_tags($text) {
    // Match empty elements (attribute values may have angle brackets).
    $re = '%
        # Regex to match an empty HTML 4.01 Transitional element.
        <                    # Opening tag opening "<" delimiter.
        (\w+)\b              # $1 Tag name.
        (?:                  # Non-capture group for optional attribute(s).
          \s+                # Attributes must be separated by whitespace.
          [\w\-.:]+          # Attribute name is required for attr=value pair.
          (?:                # Non-capture group for optional attribute value.
            \s*=\s*          # Name and value separated by "=" and optional ws.
            (?:              # Non-capture group for attrib value alternatives.
              "[^"]*"        # Double quoted string.
            | \'[^\']*\'     # Single quoted string.
            | [\w\-.:]+      # Non-quoted attrib value can be A-Z0-9-._:
            )                # End of attribute value alternatives.
          )?                 # Attribute value is optional.
        )*                   # Allow zero or more attribute=value pairs
        \s*                  # Whitespace is allowed before closing delimiter.
        >                    # Opening tag closing ">" delimiter.
        \s*                  # Content is zero or more whitespace.
        </\1\s*>             # Element closing tag.
        %x';
    while (preg_match($re, $text)) {
        // Recursively remove innermost empty elements.
        $text = preg_replace($re, '', $text);
    }
}

注意:この関数は HTML を解析しません。有効な空の HTML 4.01 要素 (定義上、ネストされていない)に対応するテキスト パターン シーケンスを単純に照合して削除します。これは、SCRIPT タグや STYLE タグ、HTML コメント、その他の開始タグの属性など、通常の HTML マークアップの外で発生する可能性のある同じテキスト パターンも誤って照合して削除することに注意してください。この正規表現は、短いタグでは機能しません。この回答に自動的に反対票を投じるbobencファンには、この正規表現が正しく一致しない有効なHTML 4.01の空の要素を1つ示してください。この正規表現は W3C 仕様に従っており、実際に機能します。

更新:この正規表現ソリューションは、次のように非常にありそうもない(しかし完全に有効な)ことを行うと、機能しません (有効なマークアップを誤って削除します)。

<div att="<p att='">stuff</div><div att="'></p>'">stuff</div>

概要:

考え直して、HTML パーサーを使用してください。

于 2011-04-06T21:22:31.320 に答える
1

あなたが直面している問題は、標準の正規表現と一致させることができない任意のレベルのネストです。何も残らないまで、同じ正規表現の置換を何度も適用できると思います。しかし、専用の HTML 解析ライブラリなど、より優れたソリューションがあります。

于 2011-04-06T20:00:53.127 に答える
1

正規表現ではできません。html が整形式であると仮定すると、おそらく xml パーサーを使用できます。

于 2011-04-06T20:03:39.083 に答える
0

なぜ再帰的なのか、単純に実行できます

 <(\w+)\s*>\s*</\1\s*>

それを何も置き換えず、入力が変更されなくなるまでその正規表現を適用し続けます。

于 2011-04-06T20:04:14.530 に答える