Regex替换周围的字符,同时保持两者之间的字符串


Regex replace surrounding characters while maintaining the string between

我正在使用PHP尝试将文本从Markdown的一种风格转换为另一种风格。

例如,如果我有字符串**some text**,则应该用字符串'''some text'''替换它(两边的**用"三撇号替换)。但是,字符串**some other text不应该进行任何替换,因为它没有以** 结束

目前,我正在使用以下代码:

function convertBoldText($line){
    #Regex replace double asterisk IF if is FOLLOWED by a non-asterisk character
    $tmp = preg_replace('/'*{2}(?=[^'*])/', "'''", $line);
    #Regex replace double asterisk IF if is PRECEDED by a non-asterisk character
    return preg_replace('/(?<=[^'*])'*{2}/', "'''", $tmp);
  }

但是,这段代码还替换了字符串中以双星号开头但不以双星号结尾的星号,这是不应该的。

当且仅当双星号匹配时(例如,存在打开和关闭的双星号并相互匹配),我如何使用regex替换双星号?

最大的挑战来自于将前面提到的两个例子结合在一起的情况,比如:

** these first asterisks should NOT be replaced **but these ones SHOULD**

您可以使用正则表达式来匹配**,该正则表达式后面跟有除**之外的任何文本,然后跟有**:

 function convertBoldText($line){
return preg_replace('/'*{2}(?!'s)((?:(?!'*{2}).)*)(?<!'s)'*{2}/s', "'''$1'''", $line);

}

查看IDEONE演示

Regex解释

  • '*{2}-2 * s
  • (?!'s)-两个星号后面不能有空白
  • ((?:(?!'*{2}).)*)-第1组捕获除**以外的任何文本
  • (?<!'s)-之前不能有空白
  • '*{2}-两个*
  • /s-一个点也匹配任何字符和换行符

一个更好的替代方案可以是

return preg_replace('/'*{2}(?!'s)([^*]*(?:'*(?!'*)[^*]*)*)(?<!'s)'*{2}/', "'''$1'''", $line);