RegEx匹配模式,除非转义

时间:2016-01-12 10:18:39

标签: php regex

我尝试了几种PHP降价转换器,用于将* XYZ *转换为< em>标签和** ABC **到< strong>标签。他们为我需要的东西做了一点太多,比如添加段落标签等等。

请注意,我只使用了两个降价标记

我写了一个可以正常使用的RegExp,但是我需要逃避保留的字符,因为用户想要一个字面的字符,就像我必须在我的帖子中一样。

这是我到目前为止所做的:

preg_replace("/(?<!\\\)\*\*([^\*\*]*)(?<!\\\)\*\*/", "<strong>$1</strong>", $line);

对于那些不太了解RegEx的人来说,(?<!\\\)表示如果前面有反斜杠,则不匹配以下模式。 ([^\*]*)相当于.*但更安全,因为它说匹配所有内容,直到我们得到一个双星号。 parens意味着收集这个答案,以便我可以在下一节中将其用作$ 1

我做的时候会打破'我的名字是**厄尔\ ***'。我想输出

My name is <strong>Earle*</strong>

但它输出

My name is <em></em>Earle<em></em>*

我的RegEx有什么问题,你能解释一下这些修正案是什么,以便将来的人知道吗

1 个答案:

答案 0 :(得分:1)

您需要匹配转义的实体,不能使用外观。

\*\*([^*\\]*(?:\\.[^\\*]*)*)\*\*

请参阅regex demo

<强>解释

  • \*\* - 2个主要星号
  • ([^*\\]*(?:\\.[^\\*]*)*) - 第1组匹配
    • [^*\\]* - 除*\以外的零个或多个字符
    • (?:\\.[^\\*]*)* - 零个或多个序列......
      • \\. - 任何转义序列
      • [^\\*]* - 除*\以外的零个或多个字符
  • \*\* - 2个尾随星号

正则表达式基于unroll-the-loop原则,应该足够有效,可以处理任何文本。

此外,您可以使用/s修饰符甚至支持转义的换行符。