1

我知道使用正则表达式来解析或操作 HTML/XML 是一个坏主意,我通常不会这样做。但考虑它是因为缺乏替代品。

我需要使用 C# 替换一个字符串中的文本,该字符串还不是标签的一部分(理想情况下是具有特定 id 的跨度标签)。

例如,假设我想用替代文本替换以下文本中不在跨度内的所有 ABC 实例(在我的情况下是另一个跨度)

ABC at start of line or ABC here must be replaced but, <span id="__publishingReusableFragment" >ABC inside span must not be replaced with anything. Another ABC here </span> this ABC must also be replaced

我尝试使用正则表达式,既向前看又向后看断言。沿线的各种组合

string regexPattern = "(?<!id=\"__publishingReusableFragment\").*?" + stringToMatch + ".*?(?!span)";

但放弃了。

我尝试将它加载到 XElement 中并尝试从那里创建一个编写器并获取不在节点内的文本。但也想不通。

XElement xel = XElement.Parse("<payload>" + inputString + @"</payload>");
XmlWriter requiredWriter = xel.CreateWriter();

我希望以某种方式使用编写器来获取不属于节点的字符串并替换它们。

基本上我愿意接受任何解决这个问题的建议/解决方案。

在此先感谢您的帮助。

4

2 回答 2

2

我知道它有点难看,但这会起作用

var s =
    @"ABC at start of line or ABC here must be replaced but, <span id=""__publishingReusableFragment"" >ABC inside span must not be replaced with anything. Another ABC here </span> this ABC must also be replaced";
var newS = string.Join("</span>",s.Split(new[] {"</span>"}, StringSplitOptions.None)
    .Select(t =>
        {
            var bits = t.Split(new[] {"<span"}, StringSplitOptions.None);
            bits[0] = bits[0].Replace("ABC","DEF");
            return string.Join("<span", bits);
        }));
于 2010-11-30T12:18:21.343 回答
2
resultString = Regex.Replace(subjectString, 
    @"(?<!              # assert that we can't match the following 
                        # before the current position: 
                        # An opening span tag with specified id
     <\s*span\s*id=""__publishingReusableFragment""\s*>
     (?:                # if it is not followed by...
      (?!<\s*/\s*span)  # a closing span tag
      .                 # at any position between the opening tag
     )*                 # and our text
    )                   # End of lookbehind assertion
    ABC                 # Match ABC", 
    "XYZ", RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);

将适用于所有关于 HTML 解析的警告(你似乎知道,所以我不会在这里重复它们)仍然有效。

ABC如果正则表达式前面没有开始标记并且两者之间<span id=__publishingReusableFragment">没有结束标记,则正则表达式匹配。<span>如果可以有嵌套<span>标签,它显然会失败。

于 2010-11-30T12:39:07.337 回答