正则表达式,用于删除XML标记及其内容

Vin*_*ent 3 .net c# regex xml vb.net

我有以下字符串,我想删除<bpt *>*</bpt><ept *>*</ept>(注意其中需要删除的其他标记内容),而不使用XML解析器(对于小字符串来说开销太大).

The big <bpt i="1" x="1" type="bold"><b></bpt>black<ept i="1"></b></ept> <bpt i="2" x="2" type="ulined"><u></bpt>cat<ept i="2"></u></ept> sleeps.
Run Code Online (Sandbox Code Playgroud)

VB.NET或C#中的任何正则表达式都可以.

tys*_*ock 7

如果您只想从字符串中删除所有标记,请使用此(C#):

try {
    yourstring = Regex.Replace(yourstring, "(<[be]pt[^>]+>.+?</[be]pt>)", "");
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我决定用更好的选择添加我的解决方案.如果有嵌入式标签,则前一个选项不起作用.这个新的解决方案应该删除嵌入或不嵌入的所有<**pt*>标记.此外,此解决方案使用对原始[be]匹配的反向引用,以便找到完全匹配的结束标记.此解决方案还创建了一个可重用的Regex对象,以提高性能,以便每次迭代都不必重新编译正则表达式:

bool FoundMatch = false;

try {
    Regex regex = new Regex(@"<([be])pt[^>]+>.+?</\1pt>");
    while(regex.IsMatch(yourstring) ) {
        yourstring = regex.Replace(yourstring, "");
    }
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}
Run Code Online (Sandbox Code Playgroud)

补充说明:

在评论中,用户表示担心'.' 模式匹配器将是cpu密集型.虽然在独立贪婪的'.'的情况下也是如此,但是使用非贪婪的字符'?' 导致正则表达式引擎只向前看,直到它找到模式中下一个字符与贪婪''的第一个匹配.这要求引擎一直向前看到字符串的末尾.我使用RegexBuddy作为正则表达式开发工具,它包含一个调试器,可以让您看到不同正则表达式模式的相对性能.如果需要,它还会自动评论你的正则表达式,所以我决定在这里包含这些注释来解释上面使用的正则表达式:

    // <([be])pt[^>]+>.+?</\1pt>
// 
// Match the character "<" literally «<»
// Match the regular expression below and capture its match into backreference number 1 «([be])»
//    Match a single character present in the list "be" «[be]»
// Match the characters "pt" literally «pt»
// Match any character that is not a ">" «[^>]+»
//    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
// Match the character ">" literally «>»
// Match any single character that is not a line break character «.+?»
//    Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?»
// Match the characters "</" literally «</»
// Match the same text as most recently matched by backreference number 1 «\1»
// Match the characters "pt>" literally «pt>»
Run Code Online (Sandbox Code Playgroud)