Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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 为什么两次运行同一个正则表达式会产生不同的结果?_Regex_Perl - Fatal编程技术网

Regex 为什么两次运行同一个正则表达式会产生不同的结果?

Regex 为什么两次运行同一个正则表达式会产生不同的结果?,regex,perl,Regex,Perl,在试图回答这个问题时,我遇到了一些来自Perl的正则表达式引擎的奇怪行为。我有一个字符串,其中包含两个数量,我试图与正则表达式匹配。正则表达式只匹配字符串“units/ml”之前的任意8个字符。我想抓住两个单位 此脚本仅打印匹配的第二个脚本: use warnings; use strict; my $line = 'some data 100,000 units/ml data 20,000 units/ml data'; my @array; if ($line =~ m/.{8}units

在试图回答这个问题时,我遇到了一些来自Perl的正则表达式引擎的奇怪行为。我有一个字符串,其中包含两个数量,我试图与正则表达式匹配。正则表达式只匹配字符串“units/ml”之前的任意8个字符。我想抓住两个单位

此脚本仅打印匹配的第二个脚本:

use warnings;
use strict;
my $line = 'some data 100,000 units/ml data 20,000 units/ml data';
my @array;
if ($line =~ m/.{8}units\/ml/g) {
    @array = $line =~ m/.{8}units\/ml/g;
    print join(' ', @array) . "\n";
}
其产出:

 20,000 units/ml
100,000 units/ml  20,000 units/ml
如果我运行第6行两次,则指定给@array的行:

use warnings;
use strict;
my $line = 'some data 100,000 units/ml data 20,000 units/ml data';
my @array;
if ($line =~ m/.{8}units\/ml/g) {
    @array = $line =~ m/.{8}units\/ml/g;
    # Let's run that again, for good measure...
    @array = $line =~ m/.{8}units\/ml/g;
    print join(' ', @array) . "\n";
}
其产出:

 20,000 units/ml
100,000 units/ml  20,000 units/ml

为什么这两个脚本会产生不同的结果?

这是因为if中的/g修饰符。由于if在标量上下文中计算=~值,因此它只获得匹配的第一个项。然后,在if块内,@array赋值从它停止的位置继续搜索。(这对于解析非常有用。)

当您运行额外的匹配时,您已经完成了对字符串中所有内容的匹配,因此您可以在列表上下文中从头开始,然后获得所有内容


如果您删除If中的g标志,那么事情就会按照您的预期进行。

这是因为If中的/g修饰符。由于if在标量上下文中计算=~值,因此它只获得匹配的第一个项。然后,在if块内,@array赋值从它停止的位置继续搜索。(这对于解析非常有用。)

当您运行额外的匹配时,您已经完成了对字符串中所有内容的匹配,因此您可以在列表上下文中从头开始,然后获得所有内容


如果删除If中的g标志,则一切正常。

在本例中,一个选项是在
If
语句中评估数组分配:

use Modern::Perl;

my $line = 'some data 100,000 units/ml data 20,000 units/ml data';
my @array;
if ( @array = $line =~ m/.{8}units\/ml/g ) {
    print join( ' ', @array ) . "\n";
}
输出:

100,000 units/ml  20,000 units/ml

如果需要,如果没有匹配,可以采取适当的措施。

在这种情况下,一个选项是在
if
语句中评估数组分配:

use Modern::Perl;

my $line = 'some data 100,000 units/ml data 20,000 units/ml data';
my @array;
if ( @array = $line =~ m/.{8}units\/ml/g ) {
    print join( ' ', @array ) . "\n";
}
输出:

100,000 units/ml  20,000 units/ml
如果需要,如果没有匹配,可以采取适当的措施。

问题就在这里

if ($line =~ m/.{8}units\/ml/g) { ... }
标量上下文中的全局匹配将匹配模式的下一个匹配项,并设置一个标记来说明下一个全局匹配的开始位置

在此之后,只剩下与模式匹配的
20000单位/ml
,因此它只匹配一次

要收集字符串中后跟
units/ml
的所有数字或逗号,您应该编写如下代码

use strict;
use warnings;

my $line = 'some data 100,000 units/ml data 20,000 units/ml data';

my @array = $line =~ m|([0-9,]+)\s*units/ml|g;

print "$_\n" for @array;
输出

100,000
20,000
问题就在这里

if ($line =~ m/.{8}units\/ml/g) { ... }
标量上下文中的全局匹配将匹配模式的下一个匹配项,并设置一个标记来说明下一个全局匹配的开始位置

在此之后,只剩下与模式匹配的
20000单位/ml
,因此它只匹配一次

要收集字符串中后跟
units/ml
的所有数字或逗号,您应该编写如下代码

use strict;
use warnings;

my $line = 'some data 100,000 units/ml data 20,000 units/ml data';

my @array = $line =~ m|([0-9,]+)\s*units/ml|g;

print "$_\n" for @array;
输出

100,000
20,000

是的,这和我想做的差不多。但是,您可以将my放入if语句中:
if(my@array=…){@array valid here}但不在这里
@Tanktalus-确实可以,提到这一点很好+1是的,这与我会做的非常接近。但是,您可以将my放入if语句中:
if(my@array=…){@array valid here}但不在这里
@Tanktalus-确实可以,提到这一点很好+1.