
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 不支援它們。
我做出的其他一些發現與我的問題的擴展部分相關: ^
並且$
可以作為錨點而不對其目錄代碼進行任何更改。我還發現它\pdfmatch
至少做了一些擴展。\$
當它來自純 TeX 時,您不能用作錨點\chardef
。但如果改為\def\${$}
(沒有花俏的逐字稿),則$
和\$
的行為類似。
上面的內容讓我們想知道擴展是否像 an 一樣是完整的,\edef
還是像 an 一樣只是一級\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
手冊 (rev. 905) 第 45 頁說明了的語法
\pdfmatch
[ icase ] [ subcount
⟨整數⟩ ]
⟨一般文字⟩ ⟨一般文字⟩(可擴充)
由於兩個參數都是 ⟨general text⟩,因此它們的內容物會像\message
.
因此,如果您需要轉義字元來建立正規表示式,例如\+
匹配文字+
,則需要\noexpand\+
or [+]
(請參見下面的範例)。
支援字元類[: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+}