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

C# 用于删除XML标记及其内容的正则表达式,c#,.net,xml,vb.net,regex,C#,.net,Xml,Vb.net,Regex,我有下面的字符串,我想删除*和*(注意它们里面的附加标记内容也需要删除),而不使用XML解析器(对于小字符串来说开销太大) 大黑猫睡着了。 VB.NET或C#中的任何正则表达式都可以。我想您想完全删除标记吗 (<bpt .*?>.*?</bpt>)|(<ept .*?>.*?</ept>) (.*)|(.*) 那个?在*使其非贪婪之后,它将尝试匹配尽可能少的字符 您将遇到的一个问题是嵌套标记。stuff看不到第二个,因为第一个匹配。.NET正

我有下面的字符串,我想删除
*
*
(注意它们里面的附加标记内容也需要删除),而不使用XML解析器(对于小字符串来说开销太大)

大黑猫睡着了。
VB.NET或C#中的任何正则表达式都可以。

我想您想完全删除标记吗

(<bpt .*?>.*?</bpt>)|(<ept .*?>.*?</ept>)
(.*)|(.*)
那个?在*使其非贪婪之后,它将尝试匹配尽可能少的字符


您将遇到的一个问题是嵌套标记。stuff看不到第二个,因为第一个匹配。

.NET正则表达式引擎是否支持负lookaheads?如果是,那么您可以使用

(<([eb])pt[^>]+>((?!</\2pt>).)+</\2pt>)
(]+>((?!)+)
这让大黑猫睡着了。如果删除所有匹配项,则超出上面的字符串。但是请记住,如果您有嵌套的
bpt
/
ept
元素,那么它将不起作用。
您可能还希望在某些位置添加
\s
,以允许在结束元素等中添加额外的空格。

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

试试看{
yourstring=Regex.Replace(yourstring,(]+>。+?),“”);
}捕获(参数异常){
//正则表达式中的语法错误
}
编辑:

我决定在我的解决方案中添加一个更好的选项。如果存在嵌入的标记,则前面的选项将不起作用。这个新的解决方案应该去除所有标签,无论是否嵌入。此外,此解决方案使用对原始[be]匹配的反向引用,以便找到精确匹配的结束标记。此解决方案还创建了一个可重用的正则表达式对象,以提高性能,从而使每次迭代都不必重新编译正则表达式:

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
}
bool-FoundMatch=false;
试一试{
正则表达式正则表达式=新正则表达式(@“]+>。+?”);
while(regex.IsMatch(yourstring)){
yourstring=regex.Replace(yourstring,“”);
}
}捕获(参数异常){
//正则表达式中的语法错误
}
补充说明:

在评论中,一位用户表示担心“.”模式匹配器会占用大量cpu。虽然在独立贪婪“.”的情况下也是如此,但使用非贪婪字符“?”会导致正则表达式引擎只向前看,直到找到模式中下一个字符与贪婪“.”的第一个匹配为止,而贪婪“.”则要求引擎一直向前看,直到字符串结束。我将其用作正则表达式开发工具,它包括一个调试器,可以让您查看不同正则表达式模式的相对性能。如果需要,它还会自动注释您的正则表达式,因此我决定在此处包含这些注释,以解释上面使用的正则表达式:

    // <([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>»
/]+>。+?
// 
//匹配字符“«[^>]+»
//在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)«+»
//按字面上的«>»匹配字符“>”
//匹配不是换行符的任何单个字符«.+?»
//在一次和无限次之间,尽可能少地按需扩展(惰性)«+?»
//按字面上的«pt>»匹配字符“”

你为什么说开销太大?你量过了吗?还是你在猜


如果要使用正则表达式来删除XML元素,最好确保输入XML不会使用来自不同名称空间的元素,或者包含您不想修改其内容的CDATA节


正确的(即性能和正确的)方法是使用XSLT。XSLT转换将除特定元素之外的所有内容复制到输出,这是标识转换的一个简单扩展。一旦编译了转换,它将非常快地执行。而且它不会包含任何隐藏的缺陷。

是否有任何可能的方法来获得xml文本类型的regex.pattern的全局解决方案? 这样我就不用replace函数了,shell使用regex。 问题在于分析是否按顺序出现。。 还将保留字符替换为“&等。 这是密码 “处理特殊字符功能” 友元函数ReplaceSpecChars(ByVal str作为字符串)作为字符串 Dim Arrlesthan作为新系列 比新系列更暗 如果不是IsDBNull(str),则

端函数 朋友函数FindLocationOfChar(ByVal chr作为Char,ByVal str作为String)作为集合 Dim arr作为新系列 对于i作为整数=1到str.Length()-1 如果str.ToCharArray(i,1)=chr,则 附件(i) 如果结束 下一个 返回arr 端函数

有问题吗


这是一个标准的xml,我想分析不同的标记。

您测量过吗?我在使用.NET的正则表达式引擎时遇到性能问题,但相比之下,使用xml解析器解析了大约40GB的xml文件,没有问题(不过,对于较大的字符串,您需要使用XmlReader)


请发布一个实际的代码示例,并说明您的性能要求:如果性能很重要,我怀疑
Regex
类是这里的最佳解决方案。

什么是过滤器?提取?删除?请澄清。避免使用XML解析器的原因是什么?需要过滤小字符串,因此不接受XML解析器开销able.Filter在这种情况下是删除的。a可以嵌套在a中吗?反之亦然?如果是这样的话,问题就复杂了。如果存在任意嵌套,则没有涉及正则表达式的通用解决方案,并且由于嵌套有限,您的正则表达式会变得非常庞大和丑陋。好吧,当您使用ave非良好格式的XML。问题中的标记不是XML,它有交叉层次结构。很好的一个,除了使用“.”这是非常cpu密集的,这
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
}
    // <([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>»
  str = CStr(str)
  If Len(str) > 0 Then
    str = Replace(str, "&", "&amp;")
    str = Replace(str, "'", "&apos;")
    str = Replace(str, """", "&quot;")
    arrLessThan = FindLocationOfChar("<", str)
    arrGreaterThan = FindLocationOfChar(">", str)
    str = ChangeGreaterLess(arrLessThan, arrGreaterThan, str)
    str = Replace(str, Chr(13), "chr(13)")
    str = Replace(str, Chr(10), "chr(10)")
  End If
  Return str
Else
  Return ""
End If
  Next


    str = Replace(str, ">", "&gt;")