我有以下字符串,我想删除<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.
VB.NET或C#中的任何正则表达式都可以。
答案 0 :(得分:7)
如果您只想删除字符串中的所有标记,请使用此(C#):
try {
yourstring = Regex.Replace(yourstring, "(<[be]pt[^>]+>.+?</[be]pt>)", "");
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}
编辑:
我决定用更好的选择添加我的解决方案。如果有嵌入式标签,则前一个选项不起作用。这个新的解决方案应该删除所有&lt; ** pt *&gt;标签,嵌入或不嵌入。此外,此解决方案使用对原始[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
}
附加说明:
在评论中,用户表示担心'。'模式匹配器将是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>»
答案 1 :(得分:1)
我认为你想完全放弃标签?
(<bpt .*?>.*?</bpt>)|(<ept .*?>.*?</ept>)
? *之后使它变得非贪婪,所以它会尝试匹配尽可能少的字符。
您将遇到的一个问题是嵌套标签。东西不会看到第二个,因为第一个匹配。
答案 2 :(得分:1)
为什么你说开销太大了?你测量过了吗?或者你在猜?
当有人出现类似&lt; bpt foo =“bar&gt;”&gt;
之类的东西时,使用正则表达式而不是正确的解析器是一种捷径。答案 3 :(得分:0)
.NET正则表达式引擎是否支持负面预测?如果是,那么你可以使用
(<([eb])pt[^>]+>((?!</\2pt>).)+</\2pt>)
如果删除所有匹配项,大黑猫会在上面的字符串中停留。。但请注意,如果您有嵌套的bpt
/ ept
元素,它将无效。
您可能还希望在某些位置添加\s
以允许在关闭元素等中添加额外的空格。
答案 4 :(得分:0)
如果您要使用正则表达式删除XML元素,最好确保输入XML不使用来自不同命名空间的元素,或者包含您不想修改其内容的CDATA部分。
使用XSLT正确(即,高效和正确)的方式。将除特定元素之外的所有内容复制到输出的XSLT转换是身份转换的一个简单扩展。编译转换后,它将非常快速地执行。它不会包含任何隐藏的缺陷。
答案 5 :(得分:0)
是否有任何可能的方法来获取regex.pattern的xml类型文本的全局解决方案? 这样我将摆脱替换功能和shell使用正则表达式。 麻烦的是分析&lt; &GT;是否有秩序.. 还将保留的字符替换为'&amp;等等。 这是代码 '处理特殊字符功能 朋友函数ReplaceSpecChars(ByVal str As String)As String Dim arrLessThan作为新系列 Dim arrGreaterThan作为新系列 如果不是IsDBNull(str)那么
str = CStr(str)
If Len(str) > 0 Then
str = Replace(str, "&", "&")
str = Replace(str, "'", "'")
str = Replace(str, """", """)
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
结束功能 朋友功能ChangeGreaterLess(ByVal lh As Collection,ByVal gr As Collection,ByVal str As String)As String 对于i As Integer = 0到lh.Count 如果CInt(lh.Item(i))&gt; CInt(gr.Item(i))然后 str =替换(str,“&lt;”,“&lt;”)/////////问题//// 结束如果
Next
str = Replace(str, ">", ">")
结束功能 朋友函数FindLocationOfChar(ByVal chr As Char,ByVal str As String)As Collection Dim arr As New Collection 对于i As Integer = 1到str.Length() - 1 如果str.ToCharArray(i,1)= chr那么 arr.Add(ⅰ) 万一 下一个 返回arr 结束功能
在问号上遇到麻烦
这是一个标准的xml,我想分析不同的标签..
答案 6 :(得分:0)
请发布实际代码示例并提及您的性能要求:如果性能很重要,我怀疑Regex
类是最佳解决方案。