查找字符串中的最高年份

查找字符串中的最高年份

我想根据发布日期隐藏文档的某些部分。

这是我定义我的部分的方式:

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2023} % Dates
  {Data 4}

该命令定义如下:

\newcommand*{\primarySection}[6][primary]{

  \def\dueyear{2018} % Value to be replaced.

  \ifnum\the\numexpr\year-5>\dueyear
    \secondarySection[primary]{#2}{#3}{#4}{#5}{#6}
  \else 
    \secondarySection[#1]{#2}{#3}{#4}{#5}{#6}
  \fi
}

我的目标是替换命令dueyear的值primarySection以便获取第 4 个参数中的字符串的最近年份。

在我上面的例子中,它是Jan. 1930 - June 2023。它并不总是这种形式,但它总是包含至少一个 4 位数的年份,有时是两个年份。

为了做到这一点,我认为必要的步骤是:

  1. 使用此正则表达式提取所有 4 个字符的数字[0-9]{4}并将它们插入到数组中。
  2. 过滤列表以仅保留最大值(使用冒泡排序或累加器)。
  3. 将此值定义为dueyear变量。在我们的示例中,它将是2023

我已经开始使用 expl3 包,但由于我不太了解 LaTeX,所以我无法得到我想要的结果......

目前我只能提取与年份相对应的值,但我不知道如何用它们创建数组,甚至不知道如何对它们进行排序并提取最大值...

这是我检测和提取年份的功能:

\ExplSyntaxOn
  \NewDocumentCommand{\extractMostRecentDate}{m}{
    \tl_set:Nn \l_tmpa_tl {#1}
    \regex_extract_once:nnN {([0-9]{4})} {#1} \l_uiy_result_seq
    \seq_map_inline:Nn \l_uiy_result_seq {#1 - ##1}
  }
\ExplSyntaxOff

我该如何修改这个函数以便它返回我之前提到的参数中最大的年份?

这样我就可以在我的primarySection函数中调用它来进行dueyear如下设置:

\def\dueyear{\extractMostRecentDate{#4}}

感谢您的帮助。

答案1

使用正则表达式提取年份[0-9]{4}\regex_extract_all:nnN所有匹配项都存储在序列中。此序列与和项目之间的一起\l__Skay_dates_seq使用。然后在内计算。\seq_use:Nn,max\fp_eval:n

将结果分配给\dueyear使用 的宏\edef

在此处输入图片描述

\documentclass[border=6pt]{standalone}
\newcommand{\dueyear}{}
\ExplSyntaxOn
\seq_new:N \l__Skay_dates_seq
\NewDocumentCommand { \extractMostRecentDate } { m }
  {
    \regex_extract_all:nnN { [0-9]{4} } {#1} \l__Skay_dates_seq
    \edef \dueyear { \fp_eval:n { max ( \seq_use:Nn \l__Skay_dates_seq { , } ) } }
  }
\ExplSyntaxOff
\begin{document}
\extractMostRecentDate{Jan. 1930 - June 2023}\dueyear;
\extractMostRecentDate{01/02/1934 - 05/06/1978}\dueyear
\end{document}

答案2

我会一直跟着expl3

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\primarySection}{O{primary}mmmmm}
 {
  \__sky_year_extract:n { #5 }
  \int_compare:nTF { \c_sys_year_int - 5 > \l__sky_year_recent_int }
   % replace the two following branches
   { not~recent~year~(\int_use:N \l__sky_year_recent_int) }
   { recent~year~(\int_use:N \l__sky_year_recent_int) }
 }

\int_new:N \l__sky_year_recent_int
\seq_new:N \l__sky_year_all_seq

\cs_new_protected:Nn \__sky_year_extract:n
 {
  \regex_extract_all:nnN { [0-9]{4} } { #1 } \l__sky_year_all_seq
  \seq_sort:Nn \l__sky_year_all_seq
   {
    \int_compare:nNnTF { ##1 } > { ##2 } { \sort_return_same: } { \sort_return_swapped: }
   }
  \int_set:Nn \l__sky_year_recent_int { \seq_item:Nn \l__sky_year_all_seq { 1 } }
 }

\ExplSyntaxOff

\begin{document}

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2023} % Dates
  {Data 4}

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2001} % Dates
  {Data 4}

\end{document}

由于我无法理解你的\secondarySection宏(在两种情况下你最终会得到完全相同的标记),我用显示所采用的分支的代码替换了它。

在此处输入图片描述

相关内容