这里更好:
\prg_new_conditional:Npnn \tl_if_integer:n #1 { p, T, F, TF }
{
\tl_if_blank:nTF{#1}
{
\prg_return_false:
}
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
这个名字看起来很奇怪:它实际上并不检查整数(例如-5
是一个整数但返回 false, +7
也返回 false)。 如果只有数字存在,它似乎更像是一个测试。
@zauguin名称可以,但该功能很有用,并匹配 tex book 的旧刻度以检查是否为数字。 我同意整数可以使用正则表达式来实现,但它会很慢
改进了您的评论:
\prg_new_conditional:Npnn \tl_if_digit:n #1 { p, T, F, TF }
{
\tl_if_blank:nTF{#1}
{
\prg_return_false:
}
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
\prg_generate_conditional_variant:Nnn \tl_if_digit:n { o } { p, T, F, TF }
\prg_new_conditional:Npnn \__tl_if_integer:n #1 { p, T, F, TF }
{
\exp_args:No\str_if_eq:onTF{\tl_head:n{#1}}{+}
{
\exp_args:No\tl_if_digit:oTF{\tl_tail:n{#1}}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
{
\exp_args:No\str_if_eq:onTF{\tl_head:n{#1}}{-}
{
\exp_args:No\tl_if_digit:oTF{\tl_tail:n{#1}}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
{
\prg_return_false:
}
}
}
\prg_new_conditional:Npnn \tl_if_integer:n #1 { p, T, F, TF }
{
% fast path
\tl_if_digit:nTF{#1}
{
\prg_return_true:
}
{
% slow path
\__tl_if_integer:nTF{#1}
{
\prg_return_true:
}
{
\prg_return_false:
}
}
}
@bastien-roucaries TeX 接受数字前面的多个符号,因此您的测试通常就足够了,但并非总是如此。 如果这被实施,它可以允许像这样的多个标志:
\ExplSyntaxOn
\prg_new_conditional:Npnn \str_if_integer:n #1 { p, T, F, TF }
{ \exp_after:wN \__str_if_integer_sign:N \tl_to_str:n {#1} \scan_stop: }
\cs_new:Npn \__str_if_integer_sign:N #1
{
\if:w $
\if_meaning:w - #1 F \fi:
\if_meaning:w + #1 F \fi: $
\exp_after:wN \__str_if_integer_digits:w \exp_after:wN #1
\else:
\exp_after:wN \__str_if_integer_sign:N
\fi:
}
\cs_new:Npn \__str_if_integer_digits:w #1 \scan_stop:
{
\tl_if_blank:nTF {#1}
{ \prg_return_false: }
{
\tl_if_blank:oTF { \__int_to_roman:w -0#1 }
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\cs_new:Npn \test #1
{ \typeout { #1: \str_if_integer:nTF {#1} { INT } { NOT } } }
\test { }
\test { ~ }
\test { 1 }
\test { - }
\test { -1 }
\test { +1 }
\test { +-+-+-1 }
\stop
测试是str
以防止参数中标记的扩展。 我的和您的实现都不会扩展符号,但会使用\romannumeral
扩展数字。 tl
版本可能必须根据需要扩展所有内容。
我同意提供\str_if_integer:nTF
是有意义的,但目前尚不清楚允许的整数应该是什么。 大概应该在符号之间允许空格,但不能在整数内,因为 TeX 不允许它?
基于\romannumeral
的代码会中断长字符串,并出现“数字太大”错误。 大概我们需要一个较慢的过程,一次只能抓取几个数字,但是检测数字之间的空格会很烦人。
如果字符串看起来“足够”像一个整数(我们可以决定有点松懈(但有据可查)),则可以使用\str_to_integer:nF
来清理字符串,否则将其第二个参数留在输入流中。
@blefloch \romannumeral 的记录限制是多少?
@bastien-roucaries TeX 可以处理的最大整数:2³¹−1 = 2147483647。
@PhelypeOleinik看来@blefloch意味着+-+-+-+-+-+-+-+-+-+-+-+-+0000000000000000000000000000000000000000000000000000000000000000可能会破坏\罗马数字...
那么最大字符串大小是多少?
@bastien-roucaries \romannumeral
对于非零数字仅以“数字太大”中断。 只要得到的整数在 [−2³¹−1, 2³¹−1] 范围内,TeX 就可以采用任意长的零字符串。
@bastien-roucaries @blefloch我不会忘记十六进制或八进制格式的整数。 和
-`a
也是一个整数。
l3bitset \__bitset_test_digits:nTF
中的数字有一个内部测试。 它不处理符号,因为这是不需要的,但它应该处理整数表达式。
正如@eg9刚刚暗示的那样,这里的实际用例是什么? 它是对数字字符串的用户级文档检查,还是检查字符串是否是 expl3 整数函数的有效输入。 后者在 expl3 上下文中似乎更有用,并且基本上意味着在\numexpr#1
之后什么都没有留下,因此不需要对数字字符串的缓慢检查。
@davidcarlisle这个错误是关于第一种情况,但我希望有第二次使用
我不认为我赞成使用随机扩展来扩展 L3 编程层,这些随机扩展(可能)在特殊情况下有用,但没有明确的经常需要的用例。 对我来说,这是一个这样的例子。 如果我们从那开始,我们在哪里结束? 那么我们应该支持多少特殊的“这是一些X”? 我对此投反对票; 不是核心语言。
@FrankMittelbach知道我们是否可以在 TL 上进行一些计算是有用的。 另一个可以使用正则表达式来完成,但是它在扩展上下文中不起作用(我需要这个测试在扩展上下文中工作)
毫无疑问。 但是它是否足够有用以保证将其包含在核心语言中(或者仅在实际需要时作为某些包代码的一部分提供)? 这就是我的问题,到目前为止,我还没有看到真正支持它的论点。
您可以针对“它是一个维度”、“它是否作为跳过”、“它只是字母”、“它是否包含非 ascii 字符”、“它是一种日期格式”以及,并且,问同样的问题,并且......可能性是完全开放的,对于其中的大多数,您可以构建一个或两个用例。 但 99% 的时间他们只会坐在那里占用空间。 虽然空间不再像过去那样珍贵,但它仍然增加了核心系统的复杂性和可维护性。 再说一遍,这个功能是否具有广泛且重复使用的功能? 如果是,并且我听到了令人信服的论据,它可以被视为纳入的候选者。 如果没有,它应该作为需要它的代码的一部分来实现。
@FrankMittelbach这个问题是特定于 biblatex 这里的。 我们需要测试某个字段是否为整数(考虑页码),并在可扩展的上下文中对其进行一些计算。
Ok ti 是特定的,但棘手的部分是可扩展的东西。
可能是这种测试应该只记录在案。 阅读文档我不知道该怎么做,而且 biblatex 核心认为如果一个令牌是一个整数,则无法测试(扩展可兼容)。
可能的解决方案是使正则表达式可扩展(我认为这会很好)
不要误会我的意思,我完全不反对我们在 biblatex 方面帮助您完成这项工作,而且很可能在核心上我们缺少一些应该在核心中支持它的功能。 我的观点是,核心应该限制自己满足“一般”的需求,并为编写特殊代码提供基本的一般基础,但不提供所有很少使用的扩展(例如,在这种情况下,当 biblatex未使用)。 否则我们最终会得到一组非常臃肿的命令。
使事情可扩展地工作通常会带来沉重的代价,无论是功能有限还是速度损失或两者兼而有之。 所以我怀疑尝试使正则表达式可扩展是一个好主意,但我让@blefloch对此发表评论。
但是在不更详细地了解您的用例的情况下:您的字段正在某个地方设置,并且由于需要分配而无法扩展,因此在那个阶段您可以确定您是否有整数或其他东西并记录可能的事实然后可扩展使用(不确定是否有帮助或是否可行,但可以避免一遍又一遍地测试该领域)。
最有用的评论
我同意提供
\str_if_integer:nTF
是有意义的,但目前尚不清楚允许的整数应该是什么。 大概应该在符号之间允许空格,但不能在整数内,因为 TeX 不允许它?基于
\romannumeral
的代码会中断长字符串,并出现“数字太大”错误。 大概我们需要一个较慢的过程,一次只能抓取几个数字,但是检测数字之间的空格会很烦人。如果字符串看起来“足够”像一个整数(我们可以决定有点松懈(但有据可查)),则可以使用
\str_to_integer:nF
来清理字符串,否则将其第二个参数留在输入流中。