PHP正则表达式解析避免子字符串
我正在编写一个简单的Markdown解析器,为同样使用一些LaTeX公式的页面输出HTML。例如,对于斜体字:PHP正则表达式解析避免子字符串,php,regex,Php,Regex,我正在编写一个简单的Markdown解析器,为同样使用一些LaTeX公式的页面输出HTML。例如,对于斜体字: //斜体 $content=preg\u replace\u回调( '/(\*|_)(.+)\1/', 功能(百万美元){ 返回“$m[2]”; }, $content ); 不幸的是,许多标记格式与LaTeX符号(以及代码块)冲突,因此我需要首先转义LaTeX部分,并仅在这些部分之外解析标记。LaTeX位由$和$$分隔,因此很容易发现它们: preg\u匹配(“/\$+(.*?\$
//斜体
$content=preg\u replace\u回调(
'/(\*|_)(.+)\1/',
功能(百万美元){
返回“$m[2]”;
},
$content
);
不幸的是,许多标记格式与LaTeX符号(以及代码块)冲突,因此我需要首先转义LaTeX部分,并仅在这些部分之外解析标记。LaTeX位由$
和$$
分隔,因此很容易发现它们:
preg\u匹配(“/\$+(.*?\$+/”,$content)
例如,这是这样一个页面的示例:
##章节标题
Lorem ipsum*dolores*sic amet$E=mc^2$,自:
$$
\cos(3*\pi*\sqrt{2})=\delta
$$
所以…斜体和乘法之间的冲突
我的第一个猜测是我应该将内容分成两个数组:一个包含带索引的LaTeX位,另一个包含位于LaTeX位之间的非LaTeX位,将第二个数组放在一边,然后将它们合并在一起
preg_split()。似乎可以使用PREG_SPLIT_DELIM_CAPTURE
标志来调整它,以返回所有子字符串,包括与regexp匹配的断点,但是文档没有显示使用此标志时的输出数据结构,因此我不知道如何迭代输出数组,只处理与模式不匹配的部分
此函数输出什么和/或是否有更好/更快的方法在与其他模式匹配的区域之外执行模式检测?一个选项可能是使用SKIP FAIL使同一行上仅以$
开头和结尾的部分不成为匹配的一部分
然后在捕获组中捕获*
或
,并使用反向引用\1
匹配相同的字符,而不匹配中间的相同字符
^\$+(?:\R(?!\$+$).*)*\R\$+$(*SKIP)(*FAIL)|([*_])((?:(?!\1).)+)\1
模式匹配:
^
字符串的开头
\$+
匹配1+次出现的$
(?:\R(?\$+$).*)
匹配所有不只有$
\R\$+$
仅将行与$
匹配
(*跳过)(*失败)|
跳过当前匹配的内容
([*.])
在组1中捕获*
或
((?:(?!\1)。)+)
重复匹配除捕获内容以外的所有字符
\1
反向引用到组1,与捕获的字符相同
|
范例
$content= <<<'DATA'
## Section title
Lorem ipsum *dolores* sic amet. $E = mc^2$, and since :
$$
\cos(3*\pi*\sqrt{2}) = \delta
$$
DATA;
$content = preg_replace_callback(
'/^\$+(?:\R(?!\$+$).*)*\R\$+$(*SKIP)(*FAIL)|([*_])((?:(?!\1).)+)\1/m',
function ($m) {
return "<i>" . $m[2] . "</i>";
},
$content
);
echo $content;
$content=
对于那些不熟悉您的LaTEX起始文档的人,您应该显示示例数据。非常感谢,这非常有帮助!
## Section title
Lorem ipsum <i>dolores</i> sic amet. $E = mc^2$, and since :
$$
\cos(3*\pi*\sqrt{2}) = \delta
$$
^\$+(?:\R(?!\$+$).*)*\R\$+$(*SKIP)(*FAIL)|(?<!\S)([*_])((?:(?!\1).)+)\1(?!\S)