【问题标题】:How to match string only in case it is not substring of specific string?如何仅在字符串不是特定字符串的子字符串的情况下匹配字符串?
【发布时间】:2015-11-20 14:25:17
【问题描述】:

我在一项微不足道的任务中遇到了这个问题。 HTML 文本不应包含字符 '' 和 '&'。第三个对我来说是个谜。我想使用正则表达式来查找所有 '&' 字符,但这个字符可以包含在实体名称中,即 & 可以包含。所以我对正则表达式的要求是找到所有不包含在格式 &[a-z]; 中的'&'。我不是正则表达式大师,所以我想出的最佳解决方案是这个正则表达式:

Regex _allAmps = new Regex("((&[a-z]*;))|[&]", RegexOptions.Compiled | RegexOptions.IgnoreCase));
...
List<Match> invalidChars.AddRange(_allAmps.Matches(htmlText).Cast<Match>.Where()m => m.Value.Lenght == 1);

但这是即兴创作。正则表达式匹配所有单个字符和所有实体名称,并保留仅单个字符。有没有办法编写这样的正则表达式?我尝试了否定前瞻,但这样正则表达式匹配所有 '&'chars。

【问题讨论】:

  • 你为什么不解码你得到的 HTML 并匹配普通的纯文本呢?您正在使用什么解析器(如果有)?另外,看看this answer of mine: Complete HTML Strip function
  • HtmlEncode吧。
  • 嗯,这个问题不是关于 HTML 本身,而是主要关于正则表达式。我认为一切都可以通过正则表达式完成,所以我很好奇如何做这样的事情。
  • 如果您对任何特定内容感兴趣,请发帖MVCE (minimal complete verifiable example)。此外,您的代码包含拼写错误:m.Value.LenghtCast&lt;Match&gt; 必须是 Cast&lt;Match&gt;() 我猜,并且存在 mor 问题。你知道,如果你愿意,我们也可以发布一个“即兴创作”的答案:)
  • 你不认为答案只是&amp;(?!\w*;)吗?

标签: c# regex


【解决方案1】:

您可以使用前瞻断言。

(?i)[&amp;](?!(?:[a-z]+\d+|(?:\#(?:[0-9]+|x[0-9a-f]+)));)

格式化

 (?i)                          # Case insensitive
 [&]                           # Ampersand (can make it [%&] to be thourough )
 (?!                           # Only if not an entity
      (?:
           [a-z]+\d+ 
        |  (?:
                \#
                (?:
                     [0-9]+ 
                  |  x [0-9a-f]+ 
                )
           )
      )
      ;     
 )

【讨论】:

  • 很好,但是有些命名实体包含数字作为字母。它们总是在最后,所以[a-z]+\d+ 会覆盖它们。
  • @AlanMoore - 好的,它更新了......是的,dtd 的。我想您必须临时阅读预定义的实体列表,并以此为基础建立一个正则表达式。来自 Wikipedia:“HTML 4 规范要求使用标准 DTD,并且不允许用户定义其他实体。”虽然 xml 规范允许用户定义 使用参数 %name; 字符 &amp;#..; 并命名为 &amp;name; 引用,其中 ascii 中的 name 大致等于 [A-Za-z_:][\w:.-]*。在 Unicode 中,name 涵盖了更多范围的字符。您可以注意到分号是有效的第一个字符。
  • 当我浏览 html 4 dtd 中的实体列表时,我没有注意到除字母数字之外的任何 name 字符,所以这就是为什么我没有使用 @ 987654328@。实际上,一个有效的 sgml 名称可以包括(ASCII 码)[A-Za-z_:][\w:.-]*. 所以,如果实体是整个家庭真正关心的问题,我想你可以使用它。
  • 如果我读错了,请纠正我...实际上需要第一个 | 之后的非捕获组吗?它内部的交替发生在它自己的非捕获组中。
  • @ErikE - 你说得对,不需要。这是为了强调。
【解决方案2】:

为什么不使用正则表达式边界。看看这个 http://www.rexegg.com/regex-boundaries.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多