在进行正则表达式匹配和替换时是否可以以某种方式跳过数学公式?
例如,在下面的代码中,\ProcessText
定义了一个命令,将 周围的文本转换为*
标记,就像在 Markdown 中一样。然而,*
在数学模式下,这可能会导致错误。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand \ProcessText { m }
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN
{ \*\*\* (.*?) \*\*\* }
{ \c{textbf} { \c{emph} {\1} } }
\l_tmpa_tl
\regex_replace_all:nnN
{ \*\* (.*?) \*\* }
{ \c{textbf} {\1} }
\l_tmpa_tl
\regex_replace_all:nnN
{ \* (.*?) \* }
{ \c{emph} {\1} }
\l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\ProcessText{Text with *emphasize*, **bold** and ***both***.}
\ProcessText{Text with equation $a^{*}b^{*}$.}
\ProcessText{Text with equation \( a^{*}b^{*} \).}
\end{document}
答案1
\regex_replace_all:nnN
解决方案不是使用 3 次,\regex_replace_case_all:nN
而是首先搜索正则表达式\$ (.*?) \$
,然后\c{\(} (.*?) \c{\)}
再搜索带有星号的正则表达式。
\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\NewDocumentCommand { \ProcessText } { m }
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_case_all:nN
{
{ \$ (.*?) \$ } { \0 }
{ \c{\(} (.*?) \c{\)} } { \0 }
{ \*\*\* (.*?) \*\*\* } { \c{textbf} { \c{emph} { \1 } } }
{ \*\* (.*?) \*\* } { \c{textbf} { \1 } }
{ \* (.*?) \* } { \c{emph} { \1 } }
} \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\ProcessText{Text with *emphasize*, **bold** and ***both***.}
\ProcessText{Text with equation $a^{*}b^{*}$.}
\ProcessText{Text with equation \( a^{*}b^{*} \).}
\end{document}
答案2
以下解决方案仅使用纯 TeX 和 TeX 基元。主要思想是被、和*
替换。此外,在数学模式下使用 重新定义。\a
**
\aa
***
\aaa
\a
\everymath
\def\ProcessText#1{\def\out{}\ptA#1*\end}
\def\ptA#1*{\addto\out{#1}\futurelet\next\ptB}
\def\ptB{\ifx\next\end \ea\ptZ \else
\ifx\next*\ea\ea\ea\ptC
\else \addto\out{\a}\ea\ea\ea \ptA
\fi\fi
}
\def\ptC*{\futurelet\next\ptD}
\def\ptD{\ifx\next*\ea\ptE \else \addto\out{\aa}\ea\ptA\fi}
\def\ptE*{\addto\out{\aaa}\ptA}
\def\ptZ\end{\out}
\def\a#1\a{{\it#1}}
\def\aa#1\aa{{\bf#1}}
\def\aaa#1\aaa{{\bi#1}}
\everymath{\let\a=*}
\def\addto#1#2{\ea\def\ea#1\ea{#1#2}}
\let\ea=\expandafter
\font\bi=cmbxti10
% test:
\ProcessText{Text with *emphasize*, **bold** and ***both***.}
\ProcessText{Text with equation $a^*b^*$.}
\bye