【问题标题】:C# Regex replace in string only outside tagsC# 正则表达式仅在标签外替换字符串
【发布时间】:2012-09-23 16:22:33
【问题描述】:

我有一个字符串,它代表 xml 的一部分。

string text ="word foo<tag foo='a' />another word "

我需要替换此字符串中的特定单词。所以我使用了这段代码:

Regex regex = new Regex("\\b" + co + "\\b", RegexOptions.IgnoreCase);
return regex.Replace(text, new MatchEvaluator(subZvyrazniStr));
static string     subZvyrazniStr(Match m)
    {
        return "<FtxFraze>" + m.ToString() + "</FtxFraze>";
    }

但我的代码的问题是,它还替换了标签内的字符串,我不想这样做。那么我应该添加什么,仅替换标签之外的单词?

例如:当我将变量 co 设置为“foo”时,我想返回 "word &lt;FtxFraze&gt;foo&lt;/FtxFraze&gt;&lt;tag foo='a' /&gt;another word"

谢谢

【问题讨论】:

  • 如果 XML 结构相关,则不应尝试使用正则表达式解析或修改 XML。 See this. 请改用 XML 解析器。然后您可以将正则表达式代码仅应用于文本节点。
  • 我知道,但是在这种情况下,我有很多节点,我不知道确切的结构,所以我认为使用正则表达式更快更容易

标签: c# regex


【解决方案1】:

如果您不那么挑剔,在某些情况下,这样的简单技巧可能就足够了:

\bfoo\b(?![^<>]*>)

【讨论】:

  • [^&lt;&gt;] 应该是[^&lt;]..不需要&gt;
  • 你能解释一下这个正则表达式吗?
  • @Anirudha,&gt; 帮助正则表达式引擎更快地找到匹配项,否则需要回溯。 (尽管这取决于引擎及其优化程度。)
  • @david, (?![^&lt;&gt;]*&gt;) 是一个否定的前瞻,如果单词后面跟着一个&gt;,则匹配失败,而两者之间没有&lt;,因此表明该单词在一个开放的内部标记。
【解决方案2】:

这就是你想要的

(?<!\<[\w\s]*?)\bfoo\b(?![\w\s]*?>)

作品here

我已经回答了一个相关问题here

【讨论】:

    【解决方案3】:

    试试这个正则表达式:

    Regex r = new Regex(@"\b" + rep + @".*?(?=\<)\b", RegexOptions.IgnoreCase);
    

    【讨论】:

    • 这匹配"foo &lt;tag&gt;bar&lt;/tag&gt;" 中的"foo &lt;tag&gt;bar""&lt;tag&gt;football&lt;/tag&gt;" 中的"football"。不情愿的量词,.*?,对于这项工作来说太弱了;您需要像@Qtax 那样积极排除&lt;。而且您必须在前瞻中执行此操作,因此您只使用单词 foo。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2010-09-23
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多