替换匹配的元素,包括嵌套元素
本文关键字:元素 嵌套 包括 替换 | 更新日期: 2023-09-27 18:12:42
我需要将span
的所有出现替换为id="comment_n"
,其中n
可以是任何数字,并且此合格span
的任何出现都可以有嵌套的数字。每个span
可以有不同的属性。例子:
foo <span id="comment_1">text <span id="comment_2" attr="value">text.</span></span> bar
我有这个正则表达式:
<span id="comment_'d+.+?<'/span>
但是它不包括最后一个结束的span
标签。
我需要做一个替换:
Regex.Replace(input, regex, string.Empty, RegexOptions.Multiline | RegexOptions.IgnoreCase);
演示:http://regexr.com/3bpkf
我建议使用htmllagilitypack来获取所需的内容。可以指定XPath只获取具有以comment_
开头的id
属性的<span>
标记(不区分大小写),然后删除它们。对comment_
之后的数字的额外检查可以使用正则表达式完成,也可以不使用。这里有一种方法可以删除一些具有特定属性值的标签,其中该值是用正则表达式检查的。
public string HtmlAgilityPackRemoveTagsWithSpecificAttribute(string html, string xpath, string attribute_name, Regex rx)
{
HtmlAgilityPack.HtmlDocument hap;
Uri uriResult;
if (Uri.TryCreate(html, UriKind.Absolute, out uriResult) &&
uriResult.Scheme == Uri.UriSchemeHttp)
{ // html is a URL
var doc = new HtmlAgilityPack.HtmlWeb();
hap = doc.Load(uriResult.AbsoluteUri);
}
else
{ // html is a string
hap = new HtmlAgilityPack.HtmlDocument();
hap.LoadHtml(html);
}
var nodes = hap.DocumentNode.SelectNodes(xpath);
if (nodes != null)
{
foreach (var node in nodes)
{
if (rx.IsMatch(node.Attributes[attribute_name].Value))
node.ParentNode.RemoveChild(node);
}
}
return hap.DocumentNode.OuterHtml;
}
你可以这样使用:
var res = HtmlAgilityPackRemoveTagsWithSpecificAttribute(html,
"//span[starts-with(translate(@id, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'), 'comment_')]", "id",
new Regex("(?i)^comment_[0-9]+$"));
注意translate
用于启用不区分大小写的比较(comment_
, COMMENT_
等)。如果你不需要,就使用starts-with(@id, 'comment_')]"
。
如果您多次使用regex,则可以在传递给方法之前将其实例化,或者使用静态Regex.IsMatch
并替换方法签名。
至于为什么它不包括最后一个关闭span
标签,这是因为您的regex模式中的?
,这使得它"懒惰"导致它匹配最短的令人满意的字符串,如果您删除它,匹配将包括最后一个'span'标签:
<span id="comment_'d+.+<'/span>
但是我建议使用htmllagilitypack来解析你的DOM并操纵它