我如何正则表达式匹配不属于模式的单个字符?

时间:2017-03-01 17:57:38

标签: php regex regex-negation regex-lookarounds

如果我有这样的字符串:

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

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

我接近负面看了几次,我到目前为止的最佳尝试是:

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

然而,这不会与获得这场胜利所需的所有分号相匹配。

我正在使用php。

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

请参阅regex demo

<强>详情:

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