Каковы правила 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/Регулярные_выражения/POSIX_Basic_Регулярные_выражения. На других страницах указано, что классы зависят от локали. Я вообще не могу заставить их работать \pdfmatch, и подозреваю, что я не делаю ничего неправильного; они просто не поддерживаются pdftex.

Несколько других открытий, которые я сделал, которые связаны с частью расширения моего вопроса: ^и $работают как якоря без каких-либо изменений в их catcodes. Я также обнаружил, что \pdfmatchделает по крайней мере некоторое расширение. Вы не можете использовать \$как якорь, когда он исходит из простого TeX \chardef. Но если изменить на \def\${$}(без причудливых дословных выражений), то $и \$ведут себя аналогично.

Вышеизложенное заставляет нас задуматься, является ли расширение полным, как an, \edefили только одноуровневым, как an \ifx, и какие из специальных символов TeX должны быть экранированы или переданы как catcode12. Фигурные скобки, даже сбалансированные, особенно загадочны. Рабочие примеры правил \strmatchor были бы очень признательны.

PS Я знаю о решениях regex с 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 показывает, что и строка, и регулярное выражение полностью раскрываются до начала обработки регулярного выражения.

Тесты 5–8 с нерасширяемым токеном chardef \DOLLARпоказывают, что если расширение не состоит исключительно из токенов символов, то ничего не совпадает.

решение2

Синтаксис \pdfmatchуказан на странице 45 руководства (ред. 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+}

Связанный контент