Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Perl仅匹配返回;“1”;。布尔人?为什么?_Regex_Perl_Parsing - Fatal编程技术网

Regex Perl仅匹配返回;“1”;。布尔人?为什么?

Regex Perl仅匹配返回;“1”;。布尔人?为什么?,regex,perl,parsing,Regex,Perl,Parsing,这必须是显而易见的,但我只是没有看到 我有一个包含数千条记录的文档,如下所示: Row:1 DATA: [0]37755442 [1]DDG00000010 [2]FALLS [3]IMAGE [4]Defect [5]3 [6]CLOSED 我已经设法将每个记录分开,现在我正试图解析出每个字段 我试图匹配编号的标题,这样我就可以提取成功的数据,但问题是,我的匹配在成功时只返回“1”,如果不成功,则什么也不会返回。我尝试申请的任何比赛都会发生这种情况 例如,应用于每个记录中的一个简单单词: m

这必须是显而易见的,但我只是没有看到

我有一个包含数千条记录的文档,如下所示:

Row:1 DATA:
[0]37755442
[1]DDG00000010
[2]FALLS
[3]IMAGE
[4]Defect
[5]3
[6]CLOSED
我已经设法将每个记录分开,现在我正试图解析出每个字段

我试图匹配编号的标题,这样我就可以提取成功的数据,但问题是,我的匹配在成功时只返回“1”,如果不成功,则什么也不会返回。我尝试申请的任何比赛都会发生这种情况

例如,应用于每个记录中的一个简单单词:

my($foo) = $record=~ /Defect/;
print STDOUT $foo;
如果每个记录包含“缺陷”,则为其打印“1”,如果记录包含其他内容,则不打印任何内容

或者:

$record =~ /Defect/;
print STDOUT $1;
什么也没印

$record =~ s/Defect/Blefect/
另一方面,将“缺陷”替换为“Blefect”非常好

我真的很困惑,为什么我的比赛的回报如此疯狂。 任何帮助都将不胜感激。

来自[我添加的括号中的位]:

/模式/msixpodualgc

在字符串中搜索模式匹配,如果成功,标量上下文中的将返回true[1],如果失败,将返回false[unde]。

(查看
s//
一节也很有用;-)

Perl没有一个离散的布尔类型或
true
/
false
别名,因此经常使用
1
undef
:但是,它很可能是其他值,而不会使文档出错

$1
将永远不会被定义,因为没有捕获组:是否需要?(或者更好,将正则表达式更改为具有捕获组;-)

快乐编码

my($foo) = $record=~ /Defect/;
print STDOUT $foo;
你不应该这样做

$record =~ /Defect/;
my $foo = $&; # Matched portion of the $record.
因为你的目标似乎是得到匹配的部分。 返回值为真/假,指示匹配是否成功


您可能会觉得很方便。

您需要使用捕获括号来实际捕获:

if ($record =~ /(Defect)/ ) {
    print "$1\n";
}

=~
perl运算符获取字符串(左操作数)和正则表达式(右操作数),并将字符串与RE匹配,根据RE是否匹配返回布尔值(true或false)

现在perl并没有真正的布尔类型——相反,在布尔上下文中,每个值(任何类型)都被视为“true”或“false”——大多数值都是“true”,但空字符串和未定义值的特殊“undef”值都是false。因此,当返回布尔值时,generall使用“1”表示true,使用“”(空字符串)表示false

现在,关于你的最后一个问题,如果试图打印
$1
则不会打印任何内容。只要匹配正则表达式,perl就会设置
$1
$2
。。。对于带RE的圆括号子表达式的值。但是,在您的示例中,没有带括号的子表达式,因此$1始终为空。如果你把它改成

$record =~ /(Defect)/;
print STDOUT $1;
您将得到更像您期望的东西(
Defect
,如果它匹配,则什么也没有,如果它不匹配)

我通常看到的最常见的regexp匹配习惯用法如下:

if ($string =~ /regexp with () subexpressions/) {
    ... code that uses $1 etc for the subexpressions matched
} else {
    ... code for when the expression doesn't match at all
}

我认为您真正想要的是将正则表达式括在括号中:

my($foo) = $record=~ /(Defect)/;

在列表上下文中,将返回组,而不是匹配本身。并且原始代码没有组。

如果希望匹配结果为“true”或“false”,则在标量上下文中进行模式匹配。这就是您在第一个示例中所做的。您执行了模式匹配,并将结果分配给标量my($foo)。所以$foo得到了一个“真”或“假”值

但是,如果要捕获与模式的一部分匹配的文本,请使用分组括号,然后检查相应的$variable。例如,考虑表达式:

$record =~ /(.*)ing/

单词“speaking”上的匹配将把“speak”分配给$1,“listening”将把“listen”分配给$1,等等。这就是您在第二个示例中尝试执行的操作。问题是您需要在分组括号中添加。“$record=~/Defect/”将不为$1分配任何内容,因为模式中没有分组括号。

匹配后,
$foo
中的具体内容是什么?许多人已经给了你正则表达式问题的答案,但我认为你问的是一个XY问题<代码>我正在尝试匹配编号的标题,以便能够提取出继承它们的数据:您希望最终的数据结构是什么样的?最有可能的是,它可以更快地完成比循环和regexing。嗨,谢谢你的答复。但它不应该在列表上下文中返回匹配项的列表吗@foo=($bug=~/Defect/);打印STDOUT@foo;或打印STDOUT@foo[0];将给我完全相同的东西。@ManAnimal添加一个捕获组并进行比较。:)明亮的成功了。我搜了又搜,从来没有碰到过括号。我一定是瞎了。非常感谢。这非常有帮助-谢谢。我忘记了绑定操作符在标量/列表上下文中的不同行为。