我正在使用 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);
}
但是,此代码还替换了以双星号开头但不以双星号结尾的字符串中的星号,这是不应该的。
当且仅当双星号匹配时(例如,存在打开和关闭双星号并且彼此匹配),如何使用正则表达式替换双星号?
最大的挑战来自于将前面提到的两个示例结合起来的情况,例如:
** 这些第一个星号不应被替换 **但这些星号应该**
最佳答案
您可以使用正则表达式来匹配 **
后跟除 **
之外的任何文本然后是 **
:
function convertBoldText($line){
return preg_replace('/\*{2}(?!\s)((?:(?!\*{2}).)*)(?<!\s)\*{2}/s', "'''$1'''", $line);
}
请参阅IDEONE demo
正则表达式解释:
-
\*{2}
- 2*
s -
(?!\s)
- 两个星号后面不能有空格 -
((?:(?!\*{2}).)*)
- 第 1 组捕获除**
之外的任何文本 -
(?<!\s)
- 前面不能有空格 -
\*{2}
- 两个*
s -
/s
- 点也匹配任何字符和换行符。
更好的选择是
return preg_replace('/\*{2}(?!\s)([^*]*(?:\*(?!\*)[^*]*)*)(?<!\s)\*{2}/', "'''$1'''", $line);
关于php - 正则表达式替换周围的字符,同时保留之间的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38464283/