l3regex:匹配和替换时跳过数学公式

l3regex:匹配和替换时跳过数学公式

在进行正则表达式匹配和替换时是否可以以某种方式跳过数学公式?

例如,在下面的代码中,\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

相关内容