【问题标题】:How can I regex match a single character that is not part of a pattern?如何正则表达式匹配不属于模式的单个字符?
【发布时间】:2017-03-01 17:57:38
【问题描述】:

如果我有这样的字符串:

&#263;; Joh&#263;; Smith <js@comms.com>; ;boom&#703;;woopwoop; ;

我希望匹配所有不属于该 html 实体的分号,我可以使用什么正则表达式技术?

我曾几次以负面的目光接近,到目前为止我最好的尝试如下:

(?<!&#.+?[^;]);

但是,这与将胜利带回家所需的所有分号都不匹配。

我正在使用 php。

我正在考虑先用标记替换 html 实体,然后替换分号,最后将实体替换回字符串。

这看起来很笨重和不优雅,所以我宁愿用正则表达式来做,即使它有点笨拙。

编辑:@sln 提供了一个将选择几乎所有实体的正则表达式,正如他指出的那样,这应该是试图避免某些事情的第一步。

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

虽然问题是关于如何选择除在字符串中找到的字符之外的单个字符,但我提供的数据的上下文使得这是一个非常有用的正则表达式,可以用来了解和附加到这个问题。

【问题讨论】:

  • 它在 .NET 中吗?顺便说一句,如果要删除分号,可以使用(&amp;#\w+;)|; 并替换为$1
  • 恐怕不行,在php里。
  • 所以,它更容易 - '~&amp;#\w+;(*SKIP)(*F)|;~' - 并替换为您想要的任何内容。见regex101.com/r/ZhITR4/1
  • 实体 (?i)[%&](?:[a-z]+|(?:#(?:[0-9]+|x[0-9a-f]+)) );
  • 当然。您尝试避免的一般模式是&amp;#\w+; 从我的正则表达式中可以看出,它与实体模式相去甚远。结果是什么?它不仅遗漏了大多数实体,而且匹配了非实体的文本,直接跳过了您想要匹配的 ;。是房间里的大猩猩。

标签: php regex regex-negation regex-lookarounds


【解决方案1】:

您可以匹配并跳过实体并在所有其他上下文中匹配分号:

$s = preg_replace('~&#\w+;(*SKIP)(*F)|;~', 'NEWTEXT', $s);

regex demo

详情

  • &amp;#\w+; - &amp;#,后跟 1+ 个单词字符和 ;
  • (*SKIP)(*F) - 两个 PCRE 动词在当前匹配失败并在文本匹配后继续寻找下一个匹配
  • | - 或
  • ; - 一个分号。

【讨论】:

    猜你喜欢
    • 2019-03-16
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多