Regex Perl正则表达式理解?
我正在尝试从文件中读取数据,并根据正则表达式模式将一些项添加到字符串中。我在做这件事的时候遇到了一些问题。因此,我编写了以下基本代码Regex Perl正则表达式理解?,regex,perl,Regex,Perl,我正在尝试从文件中读取数据,并根据正则表达式模式将一些项添加到字符串中。我在做这件事的时候遇到了一些问题。因此,我编写了以下基本代码 #!/usr/local/bin/perl #Regex example #Author: Sidartha Karna use warnings; use strict; my @temp = ('adasd\\', 'bbbb', 'cccc'); foreach(@temp){ next unless /(.*)\\?/; print "$
#!/usr/local/bin/perl
#Regex example
#Author: Sidartha Karna
use warnings;
use strict;
my @temp = ('adasd\\', 'bbbb', 'cccc');
foreach(@temp){
next unless /(.*)\\?/;
print "$_|$1\n" if defined $1;
}
我只需要字符串中除字符“\”以外的部分(如果可用)。所以我补充说?在前面的字符ie“\”之前。以下是输出:
adasd\|adasd\
bbbb|bbbb
cccc|cccc
第一个元素仍然有\存在。我无法确定此正则表达式中的问题。它是否与贪婪/非贪婪匹配相关?如何更正此正则表达式以找到正确的输出?如果希望在第一个斜杠(
\
)之前包含所有字符,请使用以下模式:
(.*?)\\
您编写的模式表示所有内容,直到最后一个斜杠或无,因为\\?
表示斜杠或无。这是一个贪婪的模式,所以它不会匹配任何东西。这就是为什么要将整个字符串作为输出
编辑:
对不起,我错过了斜杠是可选的。使用此(.*)(\\\\$)
$
表示行尾(\\\$)
表示斜杠或行尾,因此您的模式将尝试查找第一个斜杠。如果不能,它将匹配行尾。正则表达式中的*
将贪婪地匹配所有输入,包括最后一个反斜杠,留下一个空字符串来匹配\\?
使用非贪婪匹配是一个简单的修复方法:/^(.*?\\?$/
更新:现在需要锚定,以防止整个表达式与空字符串匹配。好的,因此我的perl fu有点生锈,但我认为问题在于kleene星形是贪婪的,
匹配任何内容。由于
将匹配任何内容,确切地说,它与\\?
之前的\
匹配的任何内容,但由于\
是可选的,因此正则表达式仍然匹配
您需要的是/(.*?\\?/
。基本上,*?
使克莱恩星变得懒惰
虽然从技术上讲,您想要的是/([^\\]*)\?/
,它匹配任何不属于\
的内容,但通常认为这种模式是一种更好的方法,因为它对正则表达式引擎更好一些。(第一种方法强制它在
上每次匹配后检查剩余的正则表达式,第二种方法允许它盲目前进,直到\
)试试这个
my @temp = ( 'adasd\\', 'bbbb', 'cccc' );
foreach (@temp) {
next unless /((?:(?!\\$).)*)/;
print "$_|$1\n" if defined $1;
}
(?:(?!\\$)*
仅当字符串末尾不是反斜杠时,才会匹配下一个字符。此断言由(?!\\$)
Try Character类强制执行,如
use warnings;
use strict;
my @temp = ('adasd\\', 'bbbb', 'cccc');
foreach(@temp){
next unless /([^\\]+)\\?/;
print "$_|$1\n" if defined $1;
}
输出:
adasd\|adasd
bbbb|bbbb
cccc|cccc
如果没有斜杠,则不匹配,但结尾的“\”字符是可选的。因此,其他两个字符串将不匹配。
(.*)
中的问号不需要,因为*
已经可以匹配空字符串。还是我错过了什么?@JoniSalonen是的,你错过了。对于abc\\string,此模式(.*)(\\\\$)将在组1中获得“abs”,而此模式(.*)(\\\$)将获得abc\,因为它将尝试匹配到最后一个斜杠或行尾。最后一个是行尾。但是,print“abc\\”=~/(.*)(\\\\$)/代码>输出“abc\”。(.*)
仍然匹配整个字符串,尽管它是可选的。这将不匹配任何内容,因为在abc
中,a和b之间没有任何内容,\\?
将不匹配任何内容。第一个字符串完全为空。您是对的。已更新以包括防止发生这种情况所需的锚。