1

我想告诉数字1和字符串之间的区别'1'

我想这样做的原因是因为我想确定成功匹配后正则表达式中捕获括号的数量。根据 perlop 文档,当模式中没有捕获组时,将返回列表 (1)。因此,如果我得到一个成功的匹配和一个列表 (1),那么我无法判断该模式是否没有括号,或者它有一个括号并且它匹配一个“1”。1如果 number和 string之间存在差异,我可以解决这种歧义'1'

4

6 回答 6

7

您可以通过使用特殊的@+数组 来判断上次成功匹配中有多少个捕获组。$#+是捕获组的数量。如果为 0,则没有捕获括号。

于 2011-11-11T19:43:44.037 回答
2

例如,按位运算符对字符串和整数表现不同:

~1 = 18446744073709551614

~'1' = Î('1' = 0x31, ~'1' = ~0x31 = 0xce = 'Î')

#!/usr/bin/perl

($b) = ('1' =~ /(1)/);
print isstring($b) ? "string\n" : "int\n";
($b) = ('1' =~ /1/);
print isstring($b) ? "string\n" : "int\n";

sub isstring() {
    return ($_[0] & ~$_[0]);
}

isstring 返回 0(作为数字按位运算的结果)为假,或“\0”(作为按位字符串运算的结果,设置 perldoc perlop)为真,因为它是一个非空字符串。

于 2011-11-11T19:32:46.707 回答
1

如果您想知道正则表达式匹配的捕获组的数量,只需计算它们。不要看他们返回的值,这似乎是你的问题:

您可以通过查看列表分配的结果来获取计数,该结果返回列表分配右侧的项目数:

my $count = my @array = $string =~ m/.../g;

如果您不需要保留捕获缓冲区,请分配给一个空列表:

my $count = () = $string =~ m/.../g;

或者分两步完成:

my @array = $string =~ m/.../g;
my $count = @array;

您还可以使用@+or变量,使用我在Mastering Perl@-的第一页中展示的一些技巧。这些数组具有每个捕获缓冲区的开始和结束位置。索引 0 中的值适用于整个模式,索引 1 中的值适用于,依此类推。然后,最后一个索引是捕获缓冲区的总数。请参阅perlvar$1

于 2011-11-11T21:23:09.083 回答
0

Perl 会根据需要自动在字符串和数字之间进行转换。在内部,它单独跟踪值。您可以使用 Devel::Peek 查看实际情况:

use Devel::Peek;
$x = 1;
$y = '1';
Dump($x);
Dump($y);

输出是:

SV = IV(0x3073f40) at 0x3073f44
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
SV = PV(0x30698cc) at 0x3073484
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x3079bb4 "1"\0
  CUR = 1
  LEN = 4

请注意,转储$x的 IV 槽有一个值,而转储的转储$y没有但在 PV 槽中有一个值。另请注意,简单地使用不同上下文中的值可以触发字符串化或数字化并填充其他插槽。例如,如果您这样做$x . ''$y + 0在查看该值之前,您会得到:

SV = PVIV(0x2b30b74) at 0x3073f44
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 1
  PV = 0x3079c5c "1"\0
  CUR = 1
  LEN = 4

在这一点上1'1'根本无法区分。

于 2011-11-11T19:40:03.150 回答
0

成功匹配后检查 $1 的定义。逻辑是这样的:

  • 如果列表为空,则模式匹配失败
  • 否则,如果定义了 $1,则列表包含所有捕获的子字符串
  • 否则匹配成功,但没有捕获
于 2011-11-11T19:47:27.667 回答
-1

您的问题没有多大意义,但您似乎想知道以下之间的区别:

$a = "foo"; 
@f = $a =~ /foo/; 

$a = "foo1"; 
@f = $a =~ /foo(1)?/; 

因为无论是否进行了捕获,它们都返回相同的东西。

答案是:不要尝试使用返回的数组。检查是否$1不等于""

于 2011-11-11T19:40:10.250 回答