宏定义:忽略前导“MR”和以非数字开头的尾随垃圾/解析 MathSciNet 返回的 mrnumber

宏定义:忽略前导“MR”和以非数字开头的尾随垃圾/解析 MathSciNet 返回的 mrnumber

我有一个 bibtex .bst 文件,它发出类似以下内容:

"\MR{" mrnumber "}" * *

为了生产如下产品:

\MR{MR123456789 (99 \#9999)}

或者:

\MR{MR123456789}

在.bbl 文件内。

然后,许多 MR 实现会对此进行解析,以生成指向该评论的一个小 URL:

\href{http://www.ams.org/mathscinet-getitem?mr=123456789}{MR123456789}

不幸的是,它不再可靠地工作,因为我现在得到的一些记录看起来像:

\MR{123456789 (99 \#9999)}

或者:

\MR{123456789}

没有初始 MR。

就(perl 兼容)正则表达式而言,我想从中捕获 $1 /^(?:MR)([0-9]*)[^0-9]*.*$/

我需要使用什么样的魔法\def才能省略可选的前导“MR”和由非数字字符开头的可选尾随垃圾?

答案1

您需要分两个阶段处理此输入。类似这样的操作应该可以解决问题:

\def\checkMR MR#1#2#3 #4\relax%
  {\ifx#1M%
     \ifx#2R\message{#3}\else\message{#1#2#3}\fi
   \else
     \message{#1#2#3}%
   \fi}
\def\MR#1{\checkMR MR#1 \relax}

如果输入是

 \MR{MR10000}

\checkMR被输入以下参数:

 \checkMR MRMR10000\relax

在这种情况下,#1是 M,#2是 R,并且数字在参数中#3(因为\checkMR是一个分隔宏,其调用必须以 开头MR,因此第一次MR出现会被 TeX 内部的宏扫描器删除)。

如果输入是

 \MR{10000}

数字是所有三个参数连接起来的结果,因为它会扩展为\checkMR MR1000\relax。中的\ifx测试\checkMR区分了这些情况。

\relax仅用于结束参数扫描。它可以是任何内容,只要它根本\checkMR不出现在原始参数中即可。\MR

编辑:抱歉,我最初忽略了空格问题,我已经调整了宏定义来处理这个问题。作为给读者的练习:看看你是否能自己配置出它的工作原理 :)

答案2

下面的操作似乎可以实现您的要求。

\def\MR#1{\futurelet\lettoken\checkMR#1 \endMRgarbage}
\def\checkMR{%
        \if\lettoken M\expandafter\doMR
        \else \expandafter\doMR\expandafter M\expandafter R%
        \fi
}
\def\doMR MR{%
        \afterassignment\skipMRgarbage
        \begingroup
        \count255=%
}
\def\skipMRgarbage#1\endMRgarbage{%
        MR%
        \the\count255
        \endgroup
}

\MR{MR10000}

\MR{12345689 (99 \#9999)}

\MR{MR323(99)}
\bye

这三个示例扩展为 MR10000、MR123456789 和 MR232。(实际上,这不仅仅是由于分配而导致的扩展,但这是基本思想。)应该很容易更改 \skipMRgarbage 的定义以生成 \href 或您想要的其他任何内容。

答案3

或者您可以清理 bibtex 并将所有 MR 编号缩减为第一个数字部分,例如 123456789 而不是 MR123456789 (23423)。这才是 MR 编号真正重要的部分,并且足以生成指向该项目的唯一链接。

我只是以这种方式保持我的 bib 文件干净,然后在参考书目之前为那些尚未提供它们的类定义以下两个宏:

\newcommand{\MR}[1]{\MRhref{#1}{MR #1}}

\newcommand{\MRhref}[2]{\href{http://www.ams.org/mathscinet-getitem?mr=#1}{#2}}

答案4

我无法抗拒:LuaTeX 解决方案。如果您将定义放在单独的 lua 文件中,则\bgroup/不是必需的,我始终建议这样做。请注意 Lua 有正则表达式(尽管与 perl 相比有所限制)。\catcode

\bgroup
\catcode`\%=11
\gdef\MR#1{
  \directlua{
  local str = ('#1'):gsub("^%a?%a?(%d+) ?.*$","%1")
  tex.sprint(str)
}}
\egroup

\MR{MR123456789}

\MR{MR123456789 (99 \#9999)}

\MR{123456789 (99 \#9999)}

\MR{123456789}

收益率达到 4 倍123456789

相关内容