
pdftex hat einen Befehl, der für mich möglicherweise nützlich ist, um zu suchen und Zeichenfolgen zu teilen: \pdfmatch
. Allerdings habe ich im Internet nur wenige funktionierende Beispiele gefunden. Die grundlegende Verwendung habe ich herausgefunden. Zum Beispiel kann ich einen regulären Ausdruck ausleihenhttps://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers, diese Zeilen:
\count255=\pdfmatch {[+-]?([0-9]*[.])?[0-9]+} {-4.06}
\message{\number\count255, \pdflastmatch0, \pdflastmatch1}
\end
erzeugen diese Ausgabe: 1, 0->-4.06, 1->4
Meine Frage lautet: Hat jemand die Erweiterungsregeln für herausgefunden \pdfmatch
und ob es mit Zeichenklassen wie umgehen kann [:alnum:]
?
Ich frage nach Zeichenklassen, weil die Suche von pdftex angeblich POSIX-kompatibel ist. Laut dieser Seite sind Zeichenklassen im POSIX-Standard:https://en.wikibooks.org/wiki/Reguläre_Ausdrücke/POSIX_Basic_Reguläre_Ausdrücke. Andere Seiten geben an, dass die Klassen lokalabhängig sind. Ich kann sie \pdfmatch
überhaupt nicht zum Laufen bringen und ich vermute, dass ich nichts falsch mache; sie werden von pdftex einfach nicht unterstützt.
Ein paar weitere Entdeckungen, die ich gemacht habe und die mit dem Erweiterungsteil meiner Frage zusammenhängen: ^
und $
funktionieren als Anker ohne Änderungen an ihren Catcodes. Ich habe auch entdeckt, dass \pdfmatch
zumindest einige Erweiterungen durchführt. Sie können nicht \$
als Anker verwenden, wenn es aus dem einfachen TeX kommt \chardef
. Aber wenn es in geändert wird \def\${$}
(kein ausgefallenes Wortlaut), dann verhalten sich $
und \$
ähnlich.
Das Obige lässt uns darüber nachdenken, ob die Erweiterung vollständig ist wie bei \edef
oder nur einstufig wie bei \ifx
und welche Sonderzeichen von TeX maskiert oder als catcode12 übergeben werden müssen. Klammern, selbst wenn sie ausgeglichen sind, sind besonders rätselhaft. Funktionierende Beispiele \strmatch
oder Regeln wären sehr willkommen.
PS: Ich kenne Regex-Lösungen mit Luatex. Ich frage mich speziell nach pdftex. Danke!
Antwort1
Der Regex-Quellcode in den PDFTEX-Quellen verfügt über eine optionale Unterstützung für Zeichenklassen, jedoch nicht über eine Gebietsschemaunterstützung. Daher ist er mit Nicht-ASCII-Zeichen nicht zuverlässig verwendbar. Jede UTF-8-Eingabe wird als mehrere Bytes und nicht als Unicode-Zeichen betrachtet.
\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
produziert
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->
wobei Test 2 zeigt, [:digit:]
dass es sich nicht um eine Zeichenklasse handelt, sondern einfach um den Zeichensatz: d i g t
Test 3 zeigt, [[:digit:]]
dass es sich um die Zeichenklasse handelt (danke @egreg)
Test 4 zeigt, dass sowohl die Zeichenfolge als auch der reguläre Ausdruck vollständig erweitert sind, bevor mit der Verarbeitung des regulären Ausdrucks begonnen wird.
Die Tests 5 bis 8 mit dem nicht erweiterbaren Chardef-Token \DOLLAR
zeigen, dass nichts übereinstimmt, wenn die Erweiterung nicht nur aus Zeichen-Token besteht.
Antwort2
Die Syntax dafür \pdfmatch
finden Sie auf Seite 45 des Handbuchs (Rev. 905).
\pdfmatch
[ icase ] [ subcount
⟨Integer⟩ ]
⟨Allgemeiner Text⟩ ⟨Allgemeiner Text⟩ (erweiterbar)
Da es sich bei beiden Argumenten um ⟨allgemeinen Text⟩ handelt, unterliegt ihr Inhalt der vollständigen Erweiterung, wie dies bei der Fall ist \message
.
Wenn Sie also zum Erstellen eines regulären Ausdrucks ein Zeichen maskieren müssen, beispielsweise \+
um ein wörtliches Ergebnis abzugleichen +
, benötigen Sie \noexpand\+
„oder“ [+]
(siehe Beispiel unten).
Die Zeichenklassen [:alpha:]
und [:digit:]
werden [:alnum:]
unterstützt (natürlich mit doppelten Klammern).
Um das Ende der Zeichenfolge abzugleichen, verwenden Sie einfach $
, und der Anfang der Zeichenfolge ist ^
.
Welcher Zeichensatz? Denken Sie daran, dass es pdftex
sich um einen 8-Bit-Zeichensatz handelt, sodass UTF-8-Unterstützung nicht in Frage kommt (in einigen Fällen kann es jedoch mit funktionieren 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
Die Konsole druckt
1: 1; 0->1x
2: 1; 1->2y
3: 1; 0->a2c+
4: 1; 4->d3f+
5: 1; 0->a2c+
6: 1; 1->à
Wenn du benutzt
\pdfmatch{\unexpanded{<regex>}}{<text>}
Der ⟨reguläre Ausdruck⟩ kann in der Standard-POSIX-Syntax sein. Das obige Beispiel 3 kann beispielsweise sein
\count255=\pdfmatch{\unexpanded{[[:alnum:]]*\+}}{a2c+d3f+}