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正则表达式分组结果添加额外字符,即使您不在正确的组中_Regex_Perl - Fatal编程技术网

Regex Perl正则表达式分组结果添加额外字符,即使您不在正确的组中

Regex Perl正则表达式分组结果添加额外字符,即使您不在正确的组中,regex,perl,Regex,Perl,在学习正则表达式分组规则的过程中,有一件事我不太清楚。我将用一个例子来说明 当我运行以下代码时: $s="Text1 Text2 Text3 0"; $s =~ s/(\S+)(\s+)(.*)/$1/; print("$s\n"); 我得到的结果是:“Text1”,这是我想要得到的。我将整个字符串分为3组,并返回第一组 但是,在执行以下操作时: $s="Text1 Text2 Text3 0"; $s =~ s/(\S+)(\s+)/$1/; print("$s\

在学习正则表达式分组规则的过程中,有一件事我不太清楚。我将用一个例子来说明

当我运行以下代码时:

$s="Text1    Text2   Text3   0";
$s =~ s/(\S+)(\s+)(.*)/$1/;
print("$s\n");
我得到的结果是:“Text1”,这是我想要得到的。我将整个字符串分为3组,并返回第一组

但是,在执行以下操作时:

$s="Text1    Text2   Text3   0";
$s =~ s/(\S+)(\s+)/$1/;
print("$s\n");
我得到的回复是:“text1text2text30”


两个regex语句之间的差异是第三组(.*)。我的问题是,我们为什么不在第二个语句中加上“Text1”?。毕竟,如果检查它,并且据我所知,我们将所有“非空白”字符分组到第一组,并返回它。第二组是空格的起始位置,因此第一组应该只包含“Text1”。为什么我们得到“text1text2text30”,即使第一个组只应用到“空白”(第二个组从这里开始)。

s/PATTERN/REPLACEMENT/
是替换运算符。它搜索与regex模式匹配的子字符串,并用REPLACEMENT替换它

“Text1 text2text3 0”
中,正则表达式
(\S+)(\S+)(.*)
匹配如下:

Text1 text2text30
^^^^^
\S+^^^^
\s+^^^^^^^^^^^^^^^^^
.*
\S+
匹配第一次运行的非空白字符(因此
$1='Text1'
),
\S+
匹配以下空格(因此
$2='
),而
*
匹配行的其余部分(因此
$3='text2text30'

然后将匹配的子字符串(即整个字符串;正则表达式匹配所有内容)替换为
$1
,即
Text1

您的第二个正则表达式,
(\S+)(\S+)
,匹配如下:

Text1 text2text30
^^^^^
\S+^^^^
\+
\S+
匹配第一次运行的非空白字符(因此
$1='Text1'
),并且
\S+
匹配以下空格(因此
$2='

这次匹配的子字符串只是
'Text1'
,而不是整个字符串,因此用
$1
替换它会删除
$2
中的空格

字符串中与模式不匹配的部分(
'text2text30'
)保持不变,留下

text1text2text30
作为替换的结果


所有分组和
$1
的东西都有点像是在转移注意力

比较

my $s = 'abcdef';
$s =~ s/c/X/;
print $s, "\n";  # abXdef


在第二个示例中,
c.*
在查找
c
(在本例中:
cdef
)后匹配字符串的整个剩余部分,因此这就是要替换的内容,而不是提取
*
匹配行的其余部分,并且所有匹配的文本都将从结果中删除。@WiktorStribiżew但是,您的答案并没有完全解释为什么在分组时(.*)很重要。我很乐意得到一个解释我所展示的两个案例的答案。谢谢。您的第二个代码只是删除第一块1+非空白字符后的空格。1) 2)
my $s = 'abcdef';
$s =~ s/c.*/X/;
print $s, "\n";  # abX