pdftex の `\pdfmatch` の拡張と特殊クラスの使用に関するルールは何ですか?

pdftex の `\pdfmatch` の拡張と特殊クラスの使用に関するルールは何ですか?

pdftexには、検索や文字列の分割に便利なコマンドがあります。 \pdfmatchしかし、インターネット上で実際に動作する例はほとんど見つかりませんでした。基本的な使い方は理解しています。たとえば、https://stackoverflow.com/questions/12643009/浮動小数点数の正規表現、これらの行:

\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 でサポートされていないだけだと思います。

私の質問の展開部分に関連する他のいくつかの発見: ^および は、$catcodes を変更せずにアンカーとして機能します。また、 は少なくともいくらかの展開を行うことも発見しました。がプレーン TeX から取得された場合、 をアンカーとして\pdfmatch使用することはできません。ただし、 に変更した場合(派手な逐語的表現はありません)、 およびは同様に動作します。\$\chardef\def\${$}$\$

上記から、展開が のように完全か\edef、 のように 1 レベルだけか\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ページに記載されています(改訂905)

\pdfmatch [ icase ] [ subcount⟨整数⟩ ]⟨一般テキスト⟩ ⟨一般テキスト⟩ (展開可能)

両方の引数は⟨一般テキスト⟩であるため、 の場合と同様に、その内容は完全に展開されます\message

したがって、正規表現を作成するために文字をエスケープする必要がある場合、たとえば\+リテラル に一致させるには+\noexpand\+または が必要です[+](以下の例を参照)。

文字クラス[:alpha:][:digit:]および が[:alnum:]サポートされています (もちろん二重括弧付き)。

文字列の末尾を一致させるには$、 を使用するだけで、文字列の先頭は です^

文字セットは何ですか? はpdftex8 ビットなので、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+}

関連情報