refs 中的正则表达式(例如 \ref{tab:foo.*} )

refs 中的正则表达式(例如 \ref{tab:foo.*} )

有时我想参考一长串的表格或图片。我已经对它们进行了分类标记,但要输入类似以下内容需要很多输入(我是个懒惰的程序员):

\ref{tab:foo1}, \ref{tab:foo2}, \ref{tab:foo3}, \ref{tab:foo4}

理想的结果如下:

1、2、3、4

如果我能在这里使用正则表达式,那不是很好吗?那就是:

\ref{tab:foo.*}

或者,甚至更好:

\ref{tab:foo[0-9]*}

我不太希望这个存在。我主要是好奇:有人知道有哪个软件包可以实现这个吗?

答案1

l3regexLaTeX3 模块可能会有所帮助。

您使用\lazylabel它来标记对象并\lazyref使用正则表达式作为其参数。

实际上,对标签的“类别”有支持,这留作练习。

请参阅文档l3regex以检查正则表达式的精确语法。

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn

\seq_clear_new:N \g_lazylabel_alllabels_seq
\seq_new:N \l_lazylabel_temp_seq

\NewDocumentCommand{\lazylabel}{O{alllabels}m}
 {
  \label{#2}
  \seq_if_in:cnF { g_lazylabel_#1_seq } { #2 }
   { \seq_gput_right:cn { g_lazylabel_#1_seq } { #2 } }
  \iow_shipout:cn { @auxout } { \newlazylabel { #1 } { #2 } }
 }
\cs_generate_variant:Nn \iow_shipout:Nn { c }

\NewDocumentCommand{\newlazylabel}{m m}
 {
  \seq_if_exist:cF { g_lazylabel_#1_seq }
   { \seq_new:c { g_lazylabel_#1_seq } }
  \seq_if_in:cnF { g_lazylabel_#1_seq } { #2 }
   { \seq_gput_right:cn { g_lazylabel_#1_seq } { #2 } }
 }

\NewDocumentCommand{\definelabelclass}{m}
 {
  \seq_clear_new:c { g_lazylabel_#1_seq }
 }

\NewDocumentCommand{\lazyref}{O{alllabels} m}
 {
  \lazylabel_extract:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \lazylabel_extract:nn #1 #2
 {
  \seq_clear:N \l_lazylabel_temp_seq
  \seq_map_inline:cn { g_lazylabel_#1_seq }
   {
    \regex_match:nnT { #2 } { ##1 } 
     {
      \seq_put_right:Nn \l_lazylabel_temp_seq { \ref{##1} }
     }
   }
  \seq_use:Nnnn \l_lazylabel_temp_seq { ~and~ } { ,~ } { ~and~ }
 }
\ExplSyntaxOff

\begin{document}

In sections \lazyref{sec:*} \dots


\section{a}\lazylabel{sec:a}
\section{b}\lazylabel{sec:b}
\begin{table}
\caption{a}\lazylabel{tab:foo}
\caption{a}\lazylabel{tab:foo1}
\caption{a}\lazylabel{tab:foo2}
\caption{a}\lazylabel{tab:bar1}
\end{table}


See tables \lazyref{tab:foo[1-9]+}

\end{document}

在此处输入图片描述

答案2

TeX 和 LaTeX 的设置并不适合“执行”正则表达式,至少在没有大量额外编程的情况下是这样。不过,您可能还是很幸运的:该cleveref软件包可能会执行您想要执行的操作。

例如,命令

\crefrange{tab:foo1}{tab:foo4}

将排版Tables 1 to 4;当然,这假设标有 的表格{tab:foo1}已编号1,并且标有 的表格{tab:foo4}已编号4。如果它们的编号为 22 和 25,则命令\crefrange{tab:foo1}{tab:foo4}将生成Tables 22 to 25

\crefrange如果第一个和最后一个标签指向连续编号的项目(这里是表格,对吧?),则该命令适用。如果不是这种情况,您可以使用该命令

\cref{tab:foo1,tab:foo2,tab:foo3,tab:foo4}

并让cleveref包对引用进行排序和(如有必要)压缩。例如,如果四个表的编号分别为3、、4和,则5上述命令将生成。如果您不想压缩连续的数字,请确保使用选项加载包;这将导致以下排版输出:。8\crefTables 3 to 5 and 8[sort]Tables 3, 4, 5 and 8

如果出于某种原因,你不是想要Table在交叉引用中包含交叉引用项的“名称”(此处:)——大概是因为您想自己提供它——您可以使用命令\labelcref而不是\cref

最后,如果你hyperref也使用该包,请务必加载cleveref hyperref

相关内容