pdftex `\pdfmatch` 的扩展和特殊类的使用规则是什么?

pdftex `\pdfmatch` 的扩展和特殊类的使用规则是什么?

pdftex 有一个命令可能对我有用,用于搜索和拆分字符串: \pdfmatch。但是,我在网上找到了一些可行的示例。我确实弄清楚了基本用法。例如,借用来自https://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers,以下几行:

\count255=\pdfmatch {[+-]?([0-9]*[.])?[0-9]+} {-4.06}
\message{\number\count255, \pdflastmatch0, \pdflastmatch1}
\end

产生以下输出: 1, 0->-4.06, 1->4

我的问题是:是否有人弄清楚了扩展规则\pdfmatch以及它是否可以处理类似的字符类[:alnum:]

我询问字符类是因为 pdftex 的搜索据称与 posix 兼容。根据此页面,字符类符合 posix 标准:https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions。其他页面表明这些类与语言环境相关。我根本无法使用它们\pdfmatch,我怀疑我没有做错什么;它们只是不受 pdftex 支持。

我还发现了一些与我的问题扩展部分相关的其他内容: ^和可以$作为锚点工作,而无需更改其 catcode。我还发现\pdfmatch至少进行了一些扩展。\$当它来自纯 TeX 时,您不能将其用作锚点\chardef。但如果更改为\def\${$}(没有花哨的逐字),则$和的\$行为类似。

以上内容让我们怀疑扩展是否像 一样完整\edef,还是像 一样只有一层\ifx,以及 TeX 的哪些特殊字符必须转义或作为 catcode12 传入。括号,即使匹配,也特别令人费解。\strmatch或规则的工作示例将不胜感激。

PS 我知道 luatex 的正则表达式解决方案。我特别想知道的是 pdftex。谢谢!

答案1

pdftex 源中的正则表达式源代码对字符类有一些可选支持,但不支持语言环境,因此不能可靠地用于非 ascii 字符,任何 UTF-8 输入都将被视为多个字节而不是 unicode 字符。

\pdfmatch {[+-]?([0-9]*[.])?[0-9]+} {-4.06}
\immediate\write500{1: \pdflastmatch0, \pdflastmatch1}

% [:digit:] is [:digt]  checking for those literal characters
\pdfmatch {[+-]?([:digit:]*[.])?[:digit:]+} {-dddg:ii.ggg}
\immediate\write500{2: \pdflastmatch0, \pdflastmatch1}

% [[:digit:]] is digit class
\pdfmatch {[+-]?([[:digit:]]*[.])?[[:digit:]]+} {-4.06}
\immediate\write500{3: \pdflastmatch0, \pdflastmatch1}

% full expansion happens for both arguments before regex processing
\def\aaa{[0-9]*[.]}
\def\bbb{[+-]?(\aaa)?}
\def\ccc{\bbb[0-9]+}

\def\DDD{4}
\def\EEE{06}
\def\FFF{-\DDD.\EEE}

\pdfmatch {\ccc} {\FFF}
\immediate\write500{4: \pdflastmatch0, \pdflastmatch1}

\chardef\DOLLAR=`$

\pdfmatch {\DOLLAR} {\$}
\immediate\write500{5: \pdflastmatch0}

\pdfmatch {\DOLLAR} {.D.*R}
\immediate\write500{6: \pdflastmatch0}


\pdfmatch {\DOLLAR} {.*}
\immediate\write500{7: \pdflastmatch0}


\pdfmatch {abc\DOLLAR} {a.*}
\immediate\write500{8: \pdflastmatch0}


\end

生产

1: 0->-4.06, 1->4.
2: 0->-dddg:ii.ggg, 1->dddg:ii.
3: 0->-4.06, 1->4.
4: 0->-4.06, 1->4.
5: -1->
6: -1->
7: -1->
8: -1->

测试 2 表明[:digit:]这不是一个字符类,而只是字符集: d i g t

测试 3 显示的[[:digit:]]是字符类(感谢@egreg)

测试 4 表明在正则表达式处理开始之前,字符串和正则表达式都已完全扩展。

使用不可扩展的 chardef 标记的测试 5-8\DOLLAR表明,如果扩展不是纯粹由字符标记组成,则不会有任何匹配项。

答案2

语法\pdfmatch在手册第 45 页 (rev. 905) 中有说明

\pdfmatch [ icase ] [ subcount⟨整数⟩ ]⟨一般文本⟩ ⟨一般文本⟩ (可扩展)

由于两个参数都是⟨一般文本⟩,它们的内容可以像 一样进行完全扩展\message

因此,如果您需要转义一个字符来制作正则表达式,比如说\+匹配文字+,您需要\noexpand\+[+](参见下面的示例)。

支持字符类[:alpha:][:digit:][:alnum:](当然带有双括号)。

为了匹配只需使用的字符串的结尾$,并且字符串的开头是^

什么字符集?回想一下,这pdftex是 8 位的,因此不可能支持 UTF-8(但在某些情况下它可以与 一起使用pdflatex)。

\documentclass{article}

\count255=\pdfmatch{[[:digit:]]x}{1x2y}
\message{^^J1: \the\count255; \pdflastmatch0}

\count255=\pdfmatch{[[:digit:]][[:alpha:]]}{12y}
\message{^^J2: \the\count255; \pdflastmatch0}

\count255=\pdfmatch{[[:alnum:]]*\noexpand\+}{a2c+d3f+}
\message{^^J3: \the\count255; \pdflastmatch0}

\count255=\pdfmatch{[[:alnum:]]*[+]$}{a2c+d3f+}
\message{^^J4: \the\count255; \pdflastmatch0}

\count255=\pdfmatch{^[[:alnum:]]*\noexpand\+}{a2c+d3f+}
\message{^^J5: \the\count255; \pdflastmatch0}

\count255=\pdfmatch{à}{aàa}
\message{^^J6: \the\count255; \pdflastmatch0}

\stop

控制台将打印

1: 1; 0->1x
2: 1; 1->2y
3: 1; 0->a2c+
4: 1; 4->d3f+
5: 1; 0->a2c+
6: 1; 1->à

如果你使用

\pdfmatch{\unexpanded{<regex>}}{<text>}

⟨regex⟩ 可以采用标准 POSIX 语法。例如,上面的示例 3 可以

\count255=\pdfmatch{\unexpanded{[[:alnum:]]*\+}}{a2c+d3f+}

相关内容