Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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
为什么';t.*是否使用此Perl正则表达式中的整个字符串?_Perl_Regex - Fatal编程技术网

为什么';t.*是否使用此Perl正则表达式中的整个字符串?

为什么';t.*是否使用此Perl正则表达式中的整个字符串?,perl,regex,Perl,Regex,为什么第一个print语句没有输出我期望的结果: first = This is a test string, sec = This is a test string 既然*和+都是贪婪的,为什么在第一个匹配中,*的内部,即“(”)的内部不消耗整个字符串 use strict; use warnings; my $string = "This is a test string"; $string =~ /((.*)*)/; print "first = $1, sec = $2\n";

为什么第一个print语句没有输出我期望的结果:

first = This is a test string, sec = This is a test string 
既然*和+都是贪婪的,为什么在第一个匹配中,*的内部,即“(”)的内部不消耗整个字符串

use strict;
use warnings;

my $string = "This is a test string";
$string =~ /((.*)*)/; 
print "first = $1, sec = $2\n";  #prints "first = This is a test string, sec ="

$string =~ /((.+)*)/;
print "first = $1, sec = $2\n";  #prints "first = This is a test string, sec = This is a test string"

在第一个正则表达式中,
*
匹配两次。第一次匹配整个字符串。第二次匹配末尾的空字符串,因为当没有其他匹配项时,
*
匹配空字符串

另一个正则表达式不会出现这种情况,因为
+
无法匹配空字符串

编辑:至于哪里去了:$2将包含上次应用
*
/
+
时匹配的内容。$1将包含
(.*)*
/
(.+)*
匹配的内容,即整个字符串。

使用“”运行它将导致:

Compiling REx "((.*)*)"
Final program:
   1: OPEN1 (3)
   3:   CURLYX[0] {0,32767} (12)
   5:     OPEN2 (7)
   7:       STAR (9) # <====
   8:         REG_ANY (0)
   9:     CLOSE2 (11)
  11:   WHILEM[1/1] (0)
  12:   NOTHING (13)
  13: CLOSE1 (15)
  15: END (0)
minlen 0 
编译REx”((.*)”
最终课程:
1:OPEN1(3)
3:CURLYX[0]{032767}(12)
5:OPEN2(7)
7:STAR(9)| 11:WHILEM[1/1](0)
whilem:匹配0中的1..32767
21<测试字符串>| 5:OPEN2(7)
21| 7:STAR(9)| 9:CLOSE2(11)| 11:WHILEM[1/1](0)
whilem:匹配0中的2..32767
whilem:检测到空匹配,正在尝试继续。。。
# --------------------------------------------------------------------------------------------
21<测试字符串>| 12:无(13)
21<测试串>| 13:CLOSE1(15)
21<测试串>| 15:结束(0)
比赛成功!

编译REx”((.+)*)
最终课程:
1:OPEN1(3)
3:CURLYX[0]{032767}(12)
5:OPEN2(7)
7:PLUS(9)| 11:WHILEM[1/1](0)
whilem:匹配0中的1..32767
21<测试字符串>| 5:OPEN2(7)
21<测试字符串>| 7:PLUS(9)| 13:CLOSE1(15)
21<测试串>| 15:结束(0)
比赛成功!

第一个正则表达式的问题是,
()*
只保存最后一个匹配项,而
*
匹配一个空字符串(即无)。因此

"aaab" =~ /(.)*/;

$1
将是
“b”
。如果将该行为与
*
匹配空字符串的事实结合起来,则可以看到内部捕获有两个匹配项:“这是一个测试字符串”和“”。由于空字符串是最后一个出现的,因此它被保存到
$2
$1
是整个捕获,因此它相当于
“这是一个测试字符串”。”
。第二种情况的效果与您预期的一样,因为
+
将不匹配空字符串。

我没有答案,但我有不同的方法来构建问题,使用更简单、可能更现实的正则表达式

前两个示例的行为与我预期的完全相同:
*
使用整个字符串,正则表达式返回只有一个元素的列表。但第三个正则表达式返回有两个元素的列表

use strict;
use warnings;
use Data::Dumper;

$_ = "foo";
print Dumper( [ /^(.*)/g ] ); # ('foo')     As expected.
print Dumper( [ /.(.*)/g ] ); # ('oo')      As expected.
print Dumper( [ /(.*)/g  ] ); # ('foo', '') Why?
到目前为止,许多答案都强调,
*
将匹配任何内容。虽然这是真的,但这一回答并没有触及问题的核心,即:为什么正则表达式引擎仍在搜索
*
已消耗完整个字符串?在其他情况下(如前两个示例),
*
不会为了更好的度量而抛出额外的空字符串


在Chas.Owens的有用注释后更新。对三个示例中的任何一个的第一次评估都会导致
*
匹配整个字符串。如果我们当时可以干预并调用
pos()
,引擎将确实位于字符串的末尾(至少当我们看到字符串时;请参阅Chas.的评论,以了解更多关于此的信息)但是,
/g
选项告诉Perl再次尝试匹配整个正则表达式。第二次尝试对于示例1和2将失败,失败将导致引擎停止搜索。但是,对于正则表达式3,引擎将获得另一个匹配:空字符串。然后,
/g
选项告诉引擎尝试整个模式再一次。现在真的没有什么可匹配的了——既没有常规字符,也没有尾随的空字符串——因此过程停止。

对。但是由于括号包围了字符串,我希望括号内的全部内容都是$2(而不仅仅是*),那么外部()匹配结束?根据你的描述,我会猜到$3,但它没有出现。@Anna组是由左括号计算的,所以$1是整个字符串,其中$2是括号的内部集合。内部匹配实际上是
$2
,外部匹配是
$1
。当内部部分第二次匹配时,它“覆盖”从第一次匹配时捕获的输出。如果内部
(.*)
匹配多次,则只有最后一次匹配被保留为
$2
@sepp2k,因为正则表达式匹配从内部*开始,它必须消耗整个字符串。那么,为什么在第一种情况下$2为空?更好的问题是“为什么这样做?”:)这仅仅是因为你对这个奇怪的边缘案例感到好奇,还是你真的在尝试使用它?Brian,我只是好奇:-)请参阅“perldoc-re”或perldoc.perl.org/re.html,这会让你想到“perldoc-perldebug”还有。@Brad&Ether:是的,老实说,我希望自己能冷静一些,理解那种输出,但我几乎无法理解。Ether指向的链接是这样的,对此我只能说,阿门:“为了理解这一典型的大量输出,人们不仅必须了解正则表达式匹配的一般工作原理,还必须了解Perl的
Matching REx "((.+)*)" against "This is a test string"
   0 <> <This is a >         |  1:OPEN1(3)
   0 <> <This is a >         |  3:CURLYX[0] {0,32767}(12)
   0 <> <This is a >         | 11:  WHILEM[1/1](0)
                                    whilem: matched 0 out of 0..32767
   0 <> <This is a >         |  5:    OPEN2(7)
   0 <> <This is a >         |  7:    PLUS(9) # <====
                                      REG_ANY can match 21 times out of 2147483647...
  21 < test string> <>       |  9:      CLOSE2(11)
  21 < test string> <>       | 11:      WHILEM[1/1](0)
                                        whilem: matched 1 out of 0..32767
  21 < test string> <>       |  5:        OPEN2(7)
  21 < test string> <>       |  7:        PLUS(9) # <====

  # This is where the outputs really start to diverge
  # ------------------------------------------------------------------------------------
                                          REG_ANY can match 0 times out of 2147483647...
                                          failed... # <==== Failed
                                        whilem: failed, trying continuation...
  # ------------------------------------------------------------------------------------

  21 < test string> <>       | 12:        NOTHING(13)
  21 < test string> <>       | 13:        CLOSE1(15)
  21 < test string> <>       | 15:        END(0)
Match successful!
"aaab" =~ /(.)*/;
use strict;
use warnings;
use Data::Dumper;

$_ = "foo";
print Dumper( [ /^(.*)/g ] ); # ('foo')     As expected.
print Dumper( [ /.(.*)/g ] ); # ('oo')      As expected.
print Dumper( [ /(.*)/g  ] ); # ('foo', '') Why?