Quais são as regras do pdftex `\pdfmatch` para expansão e uso de classes especiais?

Quais são as regras do pdftex `\pdfmatch` para expansão e uso de classes especiais?

pdftex tem um comando que é potencialmente útil para pesquisar e dividir strings: \pdfmatch. No entanto, encontrei poucos exemplos de trabalho na internet. Eu tenho o uso básico planejado. Por exemplo, pegar emprestado um regex dehttps://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers, estas linhas:

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

produza esta saída: 1, 0->-4.06, 1->4

Minha pergunta é: alguém descobriu as regras de expansão \pdfmatche se ela pode lidar com classes de personagens como [:alnum:]?

Eu pergunto sobre classes de caracteres porque a pesquisa do pdftex é supostamente compatível com posix. De acordo com esta página, as classes de personagens estão no padrão posix:https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions. Outras páginas indicam que as classes dependem da localidade. Não consigo fazer com que eles trabalhem \pdfmatche suspeito que não estou fazendo nada de errado; eles simplesmente não são suportados pelo pdftex.

Algumas outras descobertas que fiz estão relacionadas à parte de expansão da minha pergunta: ^e $funcionam como âncoras sem nenhuma alteração em seus códigos de gato. Eu também descobri que isso \pdfmatchfaz pelo menos alguma expansão. Você não pode usar \$como âncora quando se trata do TeX simples \chardef. Mas se for alterado para \def\${$}(sem fantasia literalmente), então $se \$comporte de maneira semelhante.

O que foi dito acima nos faz pensar se a expansão é completa como an \edefou apenas um nível como an \ifx, e quais dos caracteres especiais do TeX devem ser escapados ou passados ​​como catcode12. Os aparelhos, mesmo quando equilibrados, são especialmente intrigantes. Exemplos práticos \strmatchou regras seriam muito apreciados.

PS: Estou ciente das soluções regex com luatex. É especificamente sobre o pdftex que estou pensando. Obrigado!

Responder1

O código-fonte regex nas fontes pdftex tem algum suporte opcional para classes de caracteres, mas não tem suporte de localidade, portanto não é utilizável de forma confiável com caracteres não ASCII, qualquer entrada UTF-8 será vista como múltiplos bytes e não como caracteres 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

produz

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->

onde o teste 2 mostra [:digit:]não é uma classe de caracteres, mas simplesmente aquele conjunto de caracteres: d i g t

o teste 3 mostra [[:digit:]]é a classe de personagem (obrigado @egreg)

O teste 4 mostra que tanto a string quanto a regex são totalmente expandidas antes do início do processamento da regex.

Os testes 5 a 8 com o token chardef não expansível \DOLLARmostram que se a expansão não consistir puramente em tokens de caracteres, nada corresponde.

Responder2

A sintaxe para \pdfmatché indicada na página 45 do manual (rev. 905)

\pdfmatch [ icase ] [ subcount⟨inteiro⟩ ]⟨texto geral⟩ ⟨texto geral⟩ (expansível)

Como ambos os argumentos são ⟨texto geral⟩, seu conteúdo está sujeito a expansão total como acontece com \message.

Assim, se você precisar escapar de um caractere para fazer uma regex, digamos, \+para corresponder a um literal +, você precisa \noexpand\+de ou [+](veja o exemplo abaixo).

Classes de caracteres [:alpha:]e [:digit:]são [:alnum:]suportadas (com colchetes duplos, é claro).

Para corresponder ao final da string você apenas usa $, e o início da string é ^.

Qual conjunto de caracteres? Lembre-se de que pdftexé de 8 bits, portanto o suporte a UTF-8 está fora de questão (mas em alguns casos pode funcionar com 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

O console irá imprimir

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

Se você usar

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

o ⟨regex⟩ pode estar na sintaxe POSIX padrão. Por exemplo, o exemplo 3 acima pode ser

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

informação relacionada