我正在尝试从文件中读取并根据正则表达式模式将一些项添加到字符串中。这样做时我遇到了一些问题。所以,我写了以下基本代码。
#!/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;
}
如果可用,我只想要字符'\'以外的字符串部分。所以我加了?在前面的字符之前,即'\'。以下是输出:
adasd\|adasd\
bbbb|bbbb
cccc|cccc
第一个元素仍然是\ present。我无法确定这个正则表达式中的问题。它与贪婪/非贪婪匹配有关吗?如何纠正这个正则表达式以找到正确的输出?
答案 0 :(得分:2)
正则表达式中的.*
将贪婪地匹配所有输入,包括最后一个反斜杠,留下一个空字符串以匹配\\?
。
使用非贪婪的匹配是一个简单的解决方法:/^(.*?)\\?$/
更新:现在需要使用锚点来防止整个表达式匹配空字符串。
答案 1 :(得分:0)
如果您希望第一个斜杠(\
)之前的所有字符都使用此模式:
(.*?)\\
您编写的模式意味着一切,直到最后斜杠或什么都没有,因为\\?
意味着斜杠或什么都没有。这是一种贪婪的模式,所以它什么都不匹配。这就是你将整个字符串作为输出的原因。
编辑:
抱歉,我错过了斜线是可选的。使用此(.*?)(\\|$)
$
表示行尾。 (\\|$)
表示斜线或行尾,因此您的模式将尝试查找第一个斜杠。如果不能匹配线的末尾。
答案 2 :(得分:0)
好吧,所以我的perl-fu有点生疏,但我认为你遇到的问题是kleene明星贪婪且.
匹配任何东西。由于.
会匹配任何内容,实际上它与\
之前的\\?
匹配,但由于\\
是可选的,因此正则表达式仍然匹配。
你想要的是/(.*?)\\?/
。基本上*?
使Kleene明星变得懒惰。
虽然技术上你想要的是/([^\\]*)\\?/
,它匹配任何不是\
的东西。这种模式通常被认为是一种更好的方法,因为它对正则表达式引擎来说更好一点。 (第一种方式迫使它在.
的每次比赛后检查其余的正则表达式,第二种方式允许它盲目前进直到\
)
答案 3 :(得分:0)
试试这个
my @temp = ( 'adasd\\', 'bbbb', 'cccc' );
foreach (@temp) {
next unless /((?:(?!\\$).)*)/;
print "$_|$1\n" if defined $1;
}
仅当 (?:(?!\\$).)*
不是反斜杠后跟字符串结尾时,它才匹配下一个字符。此声明由negative lookahead assertion (?!\\$)
答案 4 :(得分:0)
尝试像
这样的角色类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