我尝试从字符串中提取年、月、日,并根据给定的日期写入不同的文本。我以为我可以使用xstring
和etoolbox
,但我无法让它工作。以下是代码片段:
\usepackage{xstring}
\usepackage{etoolbox}
\begin{document}
\newcommand{\Datum}{04.12.2011}
\newcommand{\Jahr}{\StrBehind[2]{\Datum}{.}}
\newcommand{\Monat}{\StrBetween[1,2]{\Datum}{.}{.}}
\newcommand{\Tag}{\StrBefore[1]{\Datum}{.}}
Jahr: \Jahr
\ifnumcomp{\Jahr}{=}{2011}{Jahr eq 2011}{Jahr neq 2011}
这会出现以下错误:
pdflatex> ! Missing number, treated as zero.
pdflatex> <to be read again>
pdflatex> \let
pdflatex> l.11 {305}
pdflatex>
pdflatex> ! Missing = inserted for \ifnum.
pdflatex> <to be read again>
但\Jahr
似乎正确包含了2011
。
答案1
请避免提供代码片段;相反,请创建完整的平均能量损失。
您正在将完整的xstring
-test 传递给。失败了。您可以通过 的可选参数ifnumcomp
保存 -test 的结果并将其传递给:xstring
\StrBehind
\ifnumcomp
\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\begin{document}
\newcommand{\Datum}{04.12.2011}
\StrBehind[2]{\Datum}{.}[\Jahr]
\StrBetween[1,2]{\Datum}{.}{.}[\Monat]
\StrBefore[1]{\Datum}{.}[\Tag]
Jahr: \Jahr
\ifnumcomp{\Jahr}{=}{2011}{Jahr eq 2011}{Jahr neq 2011}
\end{document}
也许您想结合输出和您可以使用的测试:
\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\makeatletter
\newcommand\Datum[1]{\@datum{#1}\@executetest{#1}}
\def\@datum#1{#1}
\def\@executetest#1{%
\StrBehind[2]{#1}{.}[\Jahr]
\StrBetween[1,2]{#1}{.}{.}[\Monat]
\StrBefore[1]{#1}{.}[\Tag]
}
\begin{document}
\Datum{04.12.2011}
Jahr: \Jahr
\ifnumcomp{\Jahr}{=}{2011}{Jahr eq 2011}{Jahr neq 2011}
\end{document}
答案2
现代解析包处理了一些可能需要处理的事情,但有时(或者仅仅作为一个说明性示例)直接使用 TeX 原语更简单:
\documentclass{article}
\def\datum{04.12.2011}
\def\Jahr{\expandafter\xJahr\datum\relax}
\def\Monat{\expandafter\xMonat\datum\relax}
\def\Tag{\expandafter\xTag\datum\relax}
\def\xJahr#1.#2.#3\relax{#3}
\def\xMonat#1.#2.#3\relax{#2}
\def\xTag#1.#2.#3\relax{#1}
\begin{document}
Jahr: \Jahr
\ifnum\Jahr=2011
Jahr eq 2011
\else
Jahr neq 2011
\fi
\end{document}
答案3
一个不同的实现xparse
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\datetest}{ O{\Datum} m m m }
{
\seq_set_split:Nnx \l_datetest_date_seq { . } { #1 }
\int_compare:nTF { \datetest_get:n { #2 } #3 #4 }
}
\cs_new:Npn \datetest_get:n #1
{
\prg_case_str:nnn { #1 }
{
{ Jahr } { \seq_item:Nn \l_datetest_date_seq { 2 } }
{ Monat } { \seq_item:Nn \l_datetest_date_seq { 1 } }
{ Tag } { \seq_item:Nn \l_datetest_date_seq { 0 } }
}
{ 0 }
}
\seq_new:N \l_datetest_date_seq
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff
\newcommand{\Datum}{04.8.2011}
\begin{document}
\datetest{Jahr}{=}{2011}{Jahr eq 2011}{Jahr neq 2011}
\datetest{Monat}{<=}{9}{$\le$}{$>$}
\newcommand{\mydate}{01.02.2003}
\datetest[\mydate]{Monat}{>}{3}{After March}{Before April}
\datetest[01.05.2010]{Monat}{>}{3}{After March}{Before April}
\end{document}
\datetest
默认情况下对 起作用\Datum
,但可以将宏或显式日期作为可选参数传递。要测试的项目是第一个参数,测试的类型(<
、<=
、=
、>=
或>
)是第二个参数;然后是要测试的数字以及如果测试为真或假时要执行的操作。
请注意,第二个参数是字符串,而不是命令。如果需要,可以扩展宏来定义 或\Jahr
。\Monat
\Tag