很久以前,我想解决这样一个问题:我要排版我的家庭作业,但将文件“hw1.tex”复制到“hw2.tex”,并忘记更改页面顶部的标题“家庭作业 1”。
所以我编写了一个函数(现在我已经不完全记得它是如何工作的了,或者也许我从 StackExchange 之类的地方获得了它的部分内容,但从未完全理解它):
\usepackage{substr}
\newcommand{\hwnum}{\BehindSubString{hw}{\scantokens\expandafter{\jobname\noexpand}}}
现在我可以制作Homework \hwnum
标题了。当我编译“hw1.tex”时,标题是“家庭作业 1”,当我编译“hw2.tex”时,标题变成“家庭作业 2”。
最小工作示例(假设您首先将其保存为具有适当名称的文件):
\documentclass{article}
\usepackage{substr}
\newcommand{\hwnum}{\BehindSubString{hw}{\scantokens\expandafter{\jobname\noexpand}}}
\begin{document}
This is Homework \hwnum.
\end{document}
这些天,我要排版的不仅仅是家庭作业,所以我希望能更灵活一些。
- 如果我想处理诸如“day1.tex”、“day2.tex”等文件名,而不需要更改命令中的前缀“hw”,那就更好了,尽管这不是很重要。
- 我真正想要的是从文件名(如“ch3lec7.tex”)中提取多个数字:例如“讲座 7”和“第 3 章”(或其他)。
- 综合起来,理想的函数应该能够找到文件名中的所有数字,无论它们被哪些非数字分隔。无论文件名是“ch3lec7.tex”还是“week3day7.tex”,同一个函数都可以提取 3 和 7。
有什么方法可以让我至少完成 #2,但如果可能的话,还可以完成 #1 或 #3?
答案1
下面的代码使用来自的正则表达式LaTeX3提取文件名中的所有数字,然后将它们作为\misha{1}
、、\misha{2}
... 提供。没有错误检查,因此,例如,如果您\misha{100}
的文档中有,那么此命令将默默失败,不执行任何操作。
如果您将下面的代码保存为文件ch3lec7.tex
然后运行它,您将得到输出:
以下是代码:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_generate_variant:Nn \regex_extract_all:nnN {nVN}
\seq_new:N \l_misha_seq
\regex_extract_all:nVN {\d+} \c_sys_jobname_str \l_misha_seq
\newcommand\misha[1]{\seq_item:Nn \l_misha_seq {#1}}
\ExplSyntaxOff
\begin{document}
Chapter \misha{1}, lecture \misha{2}.
\end{document}
这项工作全部由命令完成\regex_extract_all:nVN
,该命令将所有数字放入\jobname
内部 LaTeX3顺序. (正如 egreg 指出的那样,LaTeX3 将文件名存储在字符串常量中\c_sys_jobname_str
。)该命令\misha{k}
打印k
此序列的第个元素。
答案2
我可以即兴地提供四个宏:
\UD@ExtractDigitSequences{<arbitrary token sequence>}
此宏从中提取所有 catcode-12 位数字序列<arbitrary token sequence>
,并将每个 catcode-12 位数字序列嵌套到花括号中。\UD@ExtractKthDigitSequence{<number K>}{<arbitrary token sequence>}
此宏从中提取第 K 个 catcode-12-digit-sequence<arbitrary token sequence>
。\UD@ExtractDigitSequencesFromJobname
此宏从的扩展中提取所有 catcode-12-digit-sequences\jobname
,并将每个 catcode-12-digit-sequence 嵌套到花括号中。\UD@ExtractKthDigitSequenceFromJobname{<number K>}
此宏从 的扩展中提取第 K 个 catcode-12-digit-sequence\jobname
。
基本上\UD@ExtractDigitSequences{<arbitrary token sequence>}
和\UD@ExtractDigitSequencesFromJobname
是宏形成的递归循环的包装器\UD@extractDigitSequencesLoop
。
该递归循环的要点是:
\UD@extractDigitSequencesLoop
处理三个参数:
第一个参数表示 (剩余) <arbitrary token-sequence>
。
第二个参数表示迄今为止收集的大括号嵌套数字序列的集合。
第三个参数表示迄今为止为当前数字序列收集的数字集合。
首先,循环检查(剩余)是否<arbitrary token-sequence>
为空。
如果是这样,您就完成了,第二个参数将被传递,并且如果第三个参数不为空,它也将被传递,嵌套在括号中。
如果不是这样,循环将查看 (剩余) 的第一个标记<arbitrary token-sequence>
,同时将括号和空格视为需要特殊处理的情况。
如果 (remaining) 的第一个标记<arbitrary token-sequence>
既是非大括号标记又是非数字标记,则参数 3 中的当前数字序列已完成,如果不为空,则可以将其嵌套在大括号中并附加到参数 2,然后再次调用循环并从 (remaining) 中删除该标记<arbitrary token-sequence>
。
如果 (remaining) 的第一个标记<arbitrary token-sequence>
是左括号,则参数 3 中的当前数字序列已完成,如果不为空,则可以嵌套在括号中并附加到参数 2。在这种情况下,我们还需要将整个例程应用于括号嵌套的第一个组件/ (remaining) 的前导未分隔参数的结果附加到参数 2,然后<arbitrary token-sequence>
再次调用循环并从 (remaining) 中删除该未分隔参数<arbitrary token-sequence>
。
(这种情况仅在从任意标记序列中提取时才重要: \jobname-primitive 的扩展在任何情况下都不包含类别代码 1 的花括号或类别代码 2 的右括号,而是包含显式字符标记的集合,这些标记可能包含类别代码 12 的显式字符标记(其他但不包含字符代码 32(空格)和类别代码 10(空格)的显式字符标记和字符代码 32(空格)=显式非有趣的空格标记。)
如果 (remaining) 的第一个标记<arbitrary token-sequence>
是数字标记,则需要将其附加到参数 3 中的当前数字序列,然后再次调用循环并从 (remaining) 中删除该标记<arbitrary token-sequence>
。
当然你也需要定期检查
- 参数是否为空。
- 参数的第一个标记是否是左括号。
- 参数的第一个标记是否是空格标记。
- 参数的第一个标记是否是数字标记。
\UD@ExtractKthDigitSequence{<number K>}{<arbitrary token sequence>}
并将\UD@ExtractKthDigitSequenceFromJobname{<number K>}
执行该循环的结果“馈送”给另一个被调用的宏,该宏\UD@ExtractKthArg{<integer K>}{<list of undelimited args>}
反过来是从一串未限定/括号嵌套参数中传递第 K 个未限定参数的例程。
一切都已实现,以便它也可以在类似的扩展上下文中工作\csname..\endcsname
。
您既不需要像 eTeX 或 LuaTeX 这样的扩展,也不需要任何额外的 LaTeX2e 包,如 expl3 或 substr 等。
\documentclass{article}
\makeatletter
%%=============================================================================
%% Paraphernalia
%%.............................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@gobblespace{}\UD@firstoftwo{\def\UD@gobblespace}{} {}%
%%=============================================================================
%% Check whether argument is empty:
%%-----------------------------------------------------------------------------
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% Crank out the cases of \string "hitting"
%% - an opening-brace -> argument is not empty
%% - a non-brace-token -> argument is not empty
%% - a closing-brace -> argument is empty
%%.............................................................................
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%=============================================================================
%% Check whether argument's first token is a catcode-1-character
%%-----------------------------------------------------------------------------
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%
%% Basically this is a variation of \UD@CheckWhetherNull where non-emptiness
%% is ensured so that you need to only crank out the cases of \string "hitting"
%% an opening-brace or a non-brace-token.
%%.............................................................................
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@firstoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
}%
%%=============================================================================
%% Check whether brace-balanced argument starts with a space-token
%%-----------------------------------------------------------------------------
%% \UD@CheckWhetherLeadingSpace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>}%
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@CheckWhetherLeadingSpace[1]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingSpaceB.#1 }{}}%
}%
\newcommand\UD@CheckWhetherLeadingSpaceB{}%
\long\def\UD@CheckWhetherLeadingSpaceB#1 {%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%=============================================================================
%% Check whether argument does not contain "!" (unless nested in braces):
%%-----------------------------------------------------------------------------
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument which is
%% to be checked> does not contain !>}%
%% {<Tokens to be delivered in case <argument which is
%% to be checked> does contain !>
%%.............................................................................
\newcommand\UD@GobbleToExclam{}%
\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%=============================================================================
%% Check whether argument is a single explicit character-token of
%% category code 12 (other) that denotes digit:
%%-----------------------------------------------------------------------------
%% \UD@CheckWhetherdigit{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument which is
%% to be checked> is a single catcode-12-digit>}%
%% {<Tokens to be delivered in case <argument which is
%% to be checked> is not a single catcode-12-digit>
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@CheckWhetherdigitfork{}%
\long\def\UD@CheckWhetherdigitfork#1!0!1!2!3!4!5!6!7!8!9!#2#3!!!!{#2}%
\newcommand\UD@CheckWhetherdigit[1]{%
\romannumeral0%
\UD@CheckWhetherNoExclam{#1}{%
\UD@CheckWhetherdigitfork
!#1!1!2!3!4!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!#1!2!3!4!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!#1!3!4!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!#1!4!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!#1!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!#1!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!5!#1!7!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!5!6!#1!8!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!5!6!7!#1!9!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!5!6!7!8!#1!{\UD@firstoftwo\expandafter{} \UD@firstoftwo}%
!0!1!2!3!4!5!6!7!8!9!{\UD@firstoftwo\expandafter{} \UD@secondoftwo}%
!!!!%
}{\UD@firstoftwo\expandafter{} \UD@secondoftwo}%
}%
%%=============================================================================
%% Extract K-th inner undelimited argument:
%%-----------------------------------------------------------------------------
%% \UD@ExtractKthArg{<integer K>}{<list of undelimited args>}
%%
%% In case there is no K-th argument in <list of indelimited args> :
%% Does not deliver any token.
%% In case there is a K-th argument in <list of indelimited args> :
%% Does deliver that K-th argument with one level of braces removed.
%%
%% Examples:
%%
%% \UD@ExtractKthArg{0}{ABCDE} yields: <nothing>
%%
%% \UD@ExtractKthArg{3}{ABCDE} yields: C
%%
%% \UD@ExtractKthArg{3}{AB{CD}E} yields: CD
%%
%% \UD@ExtractKthArg{4}{{001}{002}{003}{004}{005}} yields: 004
%%
%% \UD@ExtractKthArg{6}{{001}{002}{003}} yields: <nothing>
%%
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@ExtractKthArg[1]{%
\romannumeral0%
% #1: <integer number K>
\expandafter\UD@ExtractKthArgCheck
\expandafter{\romannumeral\number\number#1 000}%
}%
\newcommand\UD@ExtractKthArgCheck[2]{%
\UD@CheckWhetherNull{#1}{ }{%
\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}{#2}%
}%
}%
\newcommand\UD@ExtractKthArgLoop[2]{%
\UD@CheckWhetherNull{#2}{ }{%
\UD@CheckWhetherNull{#1}{%
\UD@ExtractFirstArgLoop{#2\UD@SelDOm}%
}{%
\expandafter\UD@Exchange\expandafter{\expandafter{\UD@firstoftwo{}#2}}%
{\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}}%
}%
}%
}%
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\UD@firstoftwo{\expandafter}{} \UD@secondoftwo{}#1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \UD@ExtractDigitSequences{<token sequence>}
%%-----------------------------------------------------------------------------
%% Extracts sequences of explicit character tokens of category code 12
%% that denote digits from <token sequence>, nests each such sequence
%% into curly braces:
%%
%% E.g., \UD@ExtractDigitSequences{00foo78Bar66}
%% yields: {00}{78}{66}%
%%
%% E.g., \UD@ExtractDigitSequences{00foo78Bar66Baz543BaT954}
%% yields: {00}{78}{66}{543}{954}%
%%
%% Does not deliver any token in case <token sequence> does not contain
%% explicit character-tokens of category code 12(other) that denote
%% digits.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@ExtractDigitSequences[1]{%
\romannumeral0\UD@extractDigitSequencesLoop{#1}{}{}%
}%
\newcommand\UD@extractDigitSequencesLoop[3]{%
\UD@CheckWhetherNull{#1}{%
\UD@CheckWhetherNull{#3}{ #2}{ #2{#3}}%
}{%
\UD@CheckWhetherBrace{#1}{%
\expandafter\UD@Exchange\expandafter{%
\expandafter{\romannumeral0%
\UD@CheckWhetherNull{#3}{\UD@Exchange{{#2}}}{\UD@Exchange{{#2{#3}}}}%
{\expandafter\UD@extractDigitSequencesLoop
\expandafter{\romannumeral0\UD@ExtractKthArgCheck{m}{#1}}%
}{}%
}%
}%
{\expandafter\UD@extractDigitSequencesLoop\expandafter{\UD@firstoftwo{}#1}}%
{}%
}{%
\UD@CheckWhetherLeadingSpace{#1}{%
\UD@CheckWhetherNull{#3}{\UD@Exchange{{#2}}}{\UD@Exchange{{#2{#3}}}}%
{\expandafter\UD@extractDigitSequencesLoop\expandafter{\UD@gobblespace#1}}%
{}%
}{%
\expandafter\UD@CheckWhetherdigit
\expandafter{\romannumeral0\UD@ExtractKthArgCheck{m}{#1}}{%
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\expandafter\UD@Exchange
\expandafter{\romannumeral0\UD@ExtractKthArgCheck{m}{#1}}{#3}%
}%
}%
{\expandafter\UD@extractDigitSequencesLoop\expandafter{\UD@firstoftwo{}#1}{#2}}%
}{%
\UD@CheckWhetherNull{#3}{\UD@Exchange{{#2}}}{\UD@Exchange{{#2{#3}}}}%
{\expandafter\UD@extractDigitSequencesLoop\expandafter{\UD@firstoftwo{}#1}}%
{}%
}%
}%
}%
}%
}%
%%=============================================================================
%% \UD@ExtractKthDigitSequence{<integer K>}{<token sequence>}
%%-----------------------------------------------------------------------------
%% Extracts the K-th sequence of explicit character-tokens of category
%% code 12 (other) that denote digits from <token sequence> if existent.
%% Otherwise doesn't deliver any token.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@ExtractKthDigitSequence[2]{%
\romannumeral0%
\expandafter\UD@Exchange\expandafter{%
\expandafter{\romannumeral0\UD@extractDigitSequencesLoop{#2}{}{}}%
}{%
\expandafter\UD@ExtractKthArgCheck
\expandafter{\romannumeral\number\number#1 000}%
}%
}%
%%=============================================================================
%% \UD@ExtractDigitSequencesFromJobname
%%-----------------------------------------------------------------------------
%% Extracts sequences of explicit character tokens of category code 12
%% that denote digits from the top-level-expansion of the control-word-
%% token \jobname, nests each such sequence into curly braces:
%%
%% E.g., if \jobname = 00foo78Bar66, then
%%
%% \UD@ExtractDigitSequencesFromJobname
%%
%% yields: {00}{78}{66}%
%%
%% E.g., if \jobname = 00foo78Bar66Baz543BaT954, then
%%
%% \UD@ExtractDigitSequencesFromJobname
%%
%% yields: {00}{78}{66}{543}{954}%
%%
%% Does not deliver any token in case <token sequence> does not contain
%% explicit character-tokens of category code 12(other) that denote
%% digits.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@ExtractDigitSequencesFromJobname{%
\romannumeral0%
\expandafter\UD@extractDigitSequencesLoop\expandafter{\jobname}{}{}%
}%
%%=============================================================================
%% \UD@ExtractKthDigitSequenceFromJobname{<integer K>}
%%-----------------------------------------------------------------------------
%% Extracts the K-th sequence of explicit character-tokens of category
%% code 12 (other) that denote digits from the top-level-expansion of the
%% control-word-token \jobname if existent.
%% Otherwise doesn't deliver any token.
%%
%% Due to \romannumeral-expansion the result is delivered after two
%% expansion-steps.
%%.............................................................................
\newcommand\UD@ExtractKthDigitSequenceFromJobname[1]{%
\romannumeral
\expandafter\UD@Exchange\expandafter{\expandafter{\jobname}}%
{\expandafter\UD@secondoftwo\UD@ExtractKthDigitSequence{#1}}%
}%
\makeatother
\begin{document}
\makeatletter
\def\braceshowloop#1{%
\ifx\relax#1\expandafter\UD@firstoftwo\else\expandafter\UD@secondoftwo\fi
{}{\{#1\}\braceshowloop}%
}%
\noindent
\verb|\UD@ExtractDigitSequences{{{32}54{}t 65zk_+} 8}|:
\expandafter\expandafter\expandafter\braceshowloop
\UD@ExtractDigitSequences{{{32}54{}t 65zk_+} 8}\relax\\
\verb|\UD@ExtractKthDigitSequence{-1}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{-1}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{0}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{0}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{1}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{1}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{2}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{2}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{3}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{3}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{4}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{4}{{{32}54{}t 65zk_+} 8}\\
\verb|\UD@ExtractKthDigitSequence{5}{{{32}54{}t 65zk_+} 8}|:
\UD@ExtractKthDigitSequence{5}{{{32}54{}t 65zk_+} 8}\\
\verb|\jobname|:
\jobname\\
\verb|\UD@ExtractDigitSequencesFromJobname|:
\expandafter\expandafter\expandafter\braceshowloop
\UD@ExtractDigitSequencesFromJobname\relax\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{-1}|:
\UD@ExtractKthDigitSequenceFromJobname{-1}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{0}|:
\UD@ExtractKthDigitSequenceFromJobname{0}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{1}|:
\UD@ExtractKthDigitSequenceFromJobname{1}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{2}|:
\UD@ExtractKthDigitSequenceFromJobname{2}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{3}|:
\UD@ExtractKthDigitSequenceFromJobname{3}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{4}|:
\UD@ExtractKthDigitSequenceFromJobname{4}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{5}|:
\UD@ExtractKthDigitSequenceFromJobname{5}\\
\verb|\UD@ExtractKthDigitSequenceFromJobname{6}|:
\UD@ExtractKthDigitSequenceFromJobname{6}\\
\end{document}