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添加一个捕获组并进行比较。:)明亮的成功了。我搜了又搜,从来没有碰到过括号。我一定是瞎了。非常感谢。这非常有帮助-谢谢。我忘记了绑定操作符在标量/列表上下文中的不同行为。