正则表达式替换周围的字符,同时保持之间的字符串

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);
  }

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

当且仅当双星号匹配时(例如,开闭双星号存在并相互匹配),我如何使用正则表达式替换双星号?

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

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

您可以使用正则表达式匹配 ** 后跟任何文本但 ** 然后再跟 **:

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

}

IDEONE demo

正则表达式解释:

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

更好的选择可以是

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