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之间没有任何内容,
\\?
将不匹配任何内容。第一个字符串完全为空。您是对的。已更新以包括防止发生这种情况所需的锚。