2013-03-11 49 views
1

我想用正則表達式來查找不具有屬性的不完整的xml標籤。到目前爲止,我設法提出了這個正則表達式</?\s*([a-zA-Z0-9]?:\s+)?[a-zA-Z0-9]*(?!>),但這並不能解決問題。 在XML像這樣的: <abc> </abc> <ab> </ab <s:ab正則表達式查找不完整的xml標籤在c#

我想匹配</ab<s:ab(因爲他們都缺乏「>」結尾)。有沒有辦法在c#中使用正則表達式來做到這一點?

+6

正則表達式不適用於此 - 您應該使用XML解析器/驗證程序。 – Oded 2013-03-11 16:36:22

+0

您無法用一個正則表達式涵蓋所有可能性。你最好遵循Oded的建議。 – m0skit0 2013-03-11 16:37:44

+0

我不認爲有這麼多的可能性。這些是我感興趣的標籤類型: 2013-03-11 16:50:17

回答

0

如果您只是試圖在單個xml文件中查找錯誤,請嘗試在Google Chrome瀏覽器中打開它 - 它會顯示錯誤所在的行。

但是,如果你有很多文件需要在代碼中處理,那麼你需要比正則表達式更強大的東西。

1

你很近。您的主要問題是,當負向預測失敗時,模式回退。您可以通過將該部分放在非追溯原子組中的lookahead之前來避免這種情況:(?>no backtracking in here)

例如:

(?xi)     # turn on eXtended (ignore spaces/comments) and case-Insensitive mode 
(?>      # don't backtrack 
    < /?     # tag start (no space allowed after it) 
    [a-z0-9]+    # tag name/space 
    (?: : [a-z0-9]+)? 
    \s*     # optional spaces 
) 
(?! >)     # no ending 

注意,這將在<foo bar>匹配<foo

0

正如人們所說,這可能是徒勞的努力 - 因爲XML不是一種常規語言。然而,你的問題的一部分是你的前瞻。你只能確保它沒有緊接着一個閉角尖括號 - 這意味着即使你不想要它們,<ab<abc>也會匹配。所以你需要將整個標籤結構包含在你的lookahead中。

要得到你給了,我可以使用正則表達式的確切數據匹配:

#</?([a-z]?:)?[a-z]*(?!/?([a-z]?:)?[a-z]*>)# 

你可以在行動here看到。這裏的關鍵在於確保正則表達式引擎在任何時候都不會回溯(通過放棄一個字符)來驗證lookahead。還有其他方法可以做到這一點 - 例如possessive quantifiers,它在正常的回溯過程中拒絕放棄匹配的標記,但標準的.NET引擎不支持所有格匹配。它確實支持一個原子組 - 它的行爲方式相同,但使用一個組而不是一個量詞。你可以看到here,我已經將標記的整個開頭包裹在一個原子組中。 ((?> ...)

#(?></?([a-z]?:)?[a-z]*)(?!>)# 

你可以自由輸入自己的正則表達式如何標籤應該被格式化,但我必須說,這正則表達式已經推動可讀碼極限,擺弄合法的XML標籤名稱將會朝這個方向進一步推進。不過,我希望這有助於澄清錯誤。

+0

哈希值是什麼?這不是PHP,不需要雙引號。 – Qtax 2013-03-11 19:08:51

+0

@Qtax在Perl兼容正則表達式中使用分隔符是相當標準的。 PHP不是唯一的語言。 Perl(很明顯)和Javascript將它們嵌入語言中(儘管Javascript只允許正斜槓)。 – FrankieTheKneeMan 2013-03-11 23:34:18

+0

你是雙/嵌套在這裏引用。這種愚蠢只會在PHP中完成。其他語言爲正則表達式(Perl,JS,Ruby等)提供了特殊的引用構造(例如'/ regex /'),或者只使用常規字符串引號(Java,C++等)。在Perl中,你可以使用任何你想引用表達式的字符。我的觀點是:1)C#不會像那樣引用。 2)您已經在標記標記中引用了表達式,不需要再次引用它(儘管如此,仍然以不支持的格式)。 3)不要傳播PHP正則表達式引用瘋狂 – Qtax 2013-03-12 05:07:51