我正在使用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);