
Вопрос: Дана строка обычных текстовых символов, удалите все, что не является цифрой. Сохраните ее как макрос для дальнейшей обработки. Оставшиеся цифры должны быть записаны в порядке и иметь свой обычный код 12.
В оболочке POSIX с помощью sed
я мог бы написать:
mystring="Special: Five (5) bananas for \$1.50."
justnumerals="$(echo $mystring | sed 's/[^0-9]*//g')"
echo "$justnumerals" # Result: 5150
Это рутина для sed
командной строки, но чтобы сделать это в TeX...
expl3
регулярные выражения в помощь! Увы, после просмотра файла
interface3.pdf
в l3kernel
документации я запутался. Проблема в том, что между escape-кодами есть взаимодействие, и я, простой нытик, не могу их понять.
В общем, есть ли где-нибудь учебник для пользователя (а не для программиста) по регулярным выражениям expl3? Я не нашел его через общий поиск в Интернете. То, что я нашел, было математически насыщенным, за исключением полезного предыдущего вопросаРегулярное выражение с использованием `expl3`
Примечание: Я компилирую только с lualatex
, если это имеет значение. Но я не думал, что это имеет значение, поэтому я не ставил этот тег для вопроса.
решение1
Эквивалент вашего sed
вызова на самом деле довольно прост l3regex
:
\ExplSyntaxOn
\tl_new:N \l_rallg_mystring_tl
\tl_set:Nn \l_rallg_mystring_tl { Special:~ Five~ (5)~ bananas~ for~ \$1.50. }
\regex_replace_all:nnN { [^0-9] } {} \l_rallg_mystring_tl
\tl_analysis_show:N \l_rallg_mystring_tl
\stop
Коды категорий ваших цифр не изменятся. Это выведет на терминал/журнал:
The token list \l_rallg_mystring_tl contains the tokens:
> 5 (the character 5)
> 1 (the character 1)
> 5 (the character 5)
> 0 (the character 0).
решение2
Хотя я понимаю, что ваш вопрос является вопросом expl3, я, тем не менее, показываю здесь, как желаемый результат может быть достигнут с помощью символического цикла.
Коды цифр не изменяются, а наличие цифр в группах не создает проблем для их извлечения.
\documentclass{article}
\usepackage{tokcycle}
\stripgroupingtrue% STRIPS cat-1,2 BRACES FROM OUTPUT
\tokcycleenvironment\justnumerals
{\ifnum`##1>`/ \ifnum`##1<`:\addcytoks{##1}\fi\fi}% SEEKS NUMBER CHARS ONLY
{\processtoks{##1}}% PROCESSES GROUP CONTENT
{}% STRIPS MACROS
{}% STRIPS SPACES
\begin{document}
\def\mystring{Special: Five (5) bananas for \$1.50.
\textit{Numbers 2 and 4 in a group} Täüt}
\expandafter\justnumerals\mystring\endjustnumerals
Confirm braces stripped: \detokenize\expandafter{\the\cytoks}
\end{document}
решение3
Поскольку вы в любом случае используете luatex, вы можете использовать шаблоны Lua, которые ближе к тому, к чему вы привыкли, и, вероятно, в тысячи раз быстрее, чем l3regex.
\documentclass{article}
\makeatletter
\def\foo#1{\directlua{%
tex.print(string.gsub([[\detokenize{#1}]],"[^\@percentchar d]","") .. "")}}
\makeatother
\begin{document}
\foo{Special: Five (5) bananas for \$1.50.}
\end{document}