在Perl中,我如何判断一个字符串是否为数字?

11

我正在使用Perl将一些XML转换为JSON。 如果XML属性是数字,我不想在它周围加上引号,以便JSON将其视为数字而不是字符串。 我该如何判断Perl字符串是否为数字(仅包含0到9的数字和可能的一个小数点)?

7个回答

21

尝试使用Scalar::Util::looks_like_number:

例如:

use Scalar::Util qw(looks_like_number);

if (looks_like_number($thingy)) {
    print "looks like $thingy is a number...\n"
}

7
刚刚意识到,looks_like_number函数会将'inf'、'nan'、'1E02'等字符串返回为true,而这些字符串可能并不是你所期望的数字。 - mirod
2
为什么 1E02 不被认为是一个数字?它是表示科学计数法中的100。 - Nathan Fellman

21

JSON规范 对数字的格式提供了相当明确的规则,因此以下正则表达式应该有效:

/^-?(0|([1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?$/

4
你可以将其强制转为数字,然后将其与原始字符串进行比较。
if( $value eq $value+0 ){
  print "$value is a number\n";
}

(注意:它仅适用于简单的数字,如123或12.3)

提示:此功能仅适用于简单数字,如整数或带有一个小数点的浮点数。

1
"0" 和 "0e0" 或 "0.0" 或 "-0" 是相同的吗?Perl 通常认为是相同的,但你的测试结果相反。 - jrockway

3

假设您不需要支持不常见的东西(如科学计数法),那么这个方法几乎可以工作(而且非常简单):

#!/usr/bin/perl

my $foo = '1234.5';

if( $foo =~ /\d+/ ){
    print "$foo is a number\n";
}

它不能完全工作的原因是你可以在任何地方(尽可能多)有连字符和点,只要至少有一个数字存在。'--1--2'评估为零,而'1.2.3.4.5'评估为1.2(第二个点和之后的所有内容都被忽略)。这可能对您有影响,也可能没有。


3

我认为(从最近的经验来看),手动进行任何类型的XML->JSON转换都是错误的。在这个过程中,我遇到了许多问题,其中包括字符未正确转义。

我建议使用其中一个XML::*模块(我使用的是XML::Simple)解析您的XML,然后使用JSON::XS将其呈现为JSON。 JSON::XS允许您将Perl数据结构转换为JSON; XML::Simple将XML解析为Perl数据结构。同时,您可以根据需要操纵Perl数据结构。

关键是您不再需要关心引用/转义字符。


2

我认为来自perlfaq的这个问题可以解决您的问题。

通常的问题是定义您想要读取的确切数字是什么。

  • "-1.312"是有效的数字吗?
  • "inf"是吗?
  • 5.34123412E-03 呢?

-1

你可以在Perl中将XML读入数据结构中,让Perl的JSON库来处理它,这可能更容易。它已经有了检查功能,所以除非你的数字实际上是XML中的字符串(例如,在它后面有一个空格等),JSON->encode()会将其编码为JSON数字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接