我想在 LaTeX 数学模式下显示一些正则表达式,如下所示。
\[
(F+(A+I*)*)|(F*(A+I*)+)E
\]
但是,空格完全错误,因为 TeX 将 + 和 * 格式化为二元运算符,而不是后缀运算符。我期望后缀运算符会出现在靠近前一个操作数的位置,并且在后继元素是操作数的情况下,它们会引入一些额外的空格以防止出现歧义。
下面是一个按照我希望的方式格式化的示例。我用红色标记了不需要额外间距的地方,用绿色标记了需要额外间距的地方。不过,我愿意听取排版专家的其他格式建议。
有没有办法解决这个问题,而无需添加手动间距命令?
答案1
可以将其设置+*?
为自动充当后缀,但它的简单性取决于它们是否也需要在同一文档或同一表达式中的正常定义。
可能最简单的方法是为后缀版本设置简单的命令,例如:
\documentclass{article}
\makeatletter
\def\+{\@postfix+}
\def\*{\@postfix*}
\def\?{\@postfix?}
\def\@postfix#1{{#1}\@ifnextchar){}{\;}}
\makeatother
\begin{document}
\[
(F+(A+I*)*)|(F*(A+I*)+)E
\]
\[
(F\+(A\+I\*)\*)|(F\*(A\+I\*)\+)E
\]
\end{document}
答案2
我建议标记正则表达式,这样您就可以对它们进行任何您想要的更改。以下是可能性:
\documentclass{article}
\newcommand{\regex}[1]{\ensuremath{
\begingroup
\makeord{+}
\makeord{*}
\makeord{?}
#1
\endgroup
}}
\makeatletter
\newcommand{\makeord}[1]{
\@tempcnta=\mathcode`#1
\divide\@tempcnta by "1000
\multiply\@tempcnta by "1000
\mathcode`#1=\numexpr\the\mathcode`#1-\@tempcnta\relax
}
\makeatother
\begin{document}
\[
\regex{(F+(A+I*)*)|(F*(A+I*)+)E}
\]
\end{document}
您也可以\regex
直接在文本模式下使用。
“magic”\makeord
宏从字符中剥离出其数学原子类型:数学代码是一个 15 位数字;三个最高有效数字告诉 TeX 原子类型,0 对应于“普通”。所以我们这样做
n - (n 模 4096)
其中 n 是字符的数学代码,并将其指定为数学代码:打印的字符是相同的,但就间距而言被视为普通符号。
添加所需间距的另一种方法是使用
\newcommand{\makeord}[1]{
\edef\@tempa{\the\mathcode`#1 }
\begingroup\lccode`~=`#1
\lowercase{\endgroup\edef~}{\mathpunct{\mathchar\@tempa}}
\mathcode`#1="8000
}
使用与前面相同的正则表达式,结果为
然而,这不适用于以下情况
A*?
*
因为和之间会插入一个空格?
。
这里的技巧是将+
、*
和?
视为标点符号。