Regex 正则表达式-零宽度';单词边界';使交替模式正确匹配
关于: 如果输入:Regex 正则表达式-零宽度';单词边界';使交替模式正确匹配,regex,perl,Regex,Perl,关于: 如果输入: home/////test/tmp/ 以及所需的转换: /home/test/tmp/ (和其他文件路径类似的模式,需要尾随斜杠和前导斜杠,但不能使用双精度。例如,/home/test/tmp/通过,但/home/test/tmp获得尾随斜杠,等等。) 使用三重正则表达式 s,^/*,/,; #prefix s,/*$,/,; #suffix s,/+,/,g; #double slashes anywhere else. 给出了正确的结果: #!/usr/bin/
home/////test/tmp/
以及所需的转换:
/home/test/tmp/
(和其他文件路径类似的模式,需要尾随斜杠和前导斜杠,但不能使用双精度。例如,/home/test/tmp/
通过,但/home/test/tmp
获得尾随斜杠,等等。)
使用三重正则表达式
s,^/*,/,; #prefix
s,/*$,/,; #suffix
s,/+,/,g; #double slashes anywhere else.
给出了正确的结果:
#!/usr/bin/env perl
use strict;
use warnings;
my $str = 'home/////teledyne/tmp/';
$str =~ s,^/*,/,; #prefix
$str =~ s,/*$,/,; #suffix
$str =~ s,/+,/,g; #double slashes anywhere else.
print $str;
但如果我尝试使用交替组合这些模式,我会得到:
s,(^/*|/+|/*$),/,g
这看起来应该有用。。。实际上没有,我得到了一个双斜杠
但添加零宽度匹配,效果很好:
s,(^/*|/+|\b/*$),/,g;
有没有人能帮我了解一下在交替组中发生了什么不同的事情,以及把
\b
放在那里是否可能会有问题 这里有一个单独的正则表达式来完成所有操作:
s='home/////test/tmp/'
perl -pe 's~^(?!/)|(?<!/)$|/{2,}~/~g' <<< "$s"
/home/test/tmp/
s='home/test/tmp'
perl -pe 's~^(?!/)|(?<!/)$|/{2,}~/~g' <<< "$s"
/home/test/tmp/
s='home///test/tmp/'
perl-pe的~^(?!/)|(?原因是,/g
下的/+
交替匹配最后一个斜杠–然后由于锚的存在而继续搜索。它从最后一个替换后的位置继续,因此在最后一个斜杠之后。该搜索匹配$
处的零斜杠,并添加/
我们可以通过
perl -wE'
$_ = "home/dir///end/";
while (m{( ^/* | /+ | /*$ )}gx) { say "Got |$1| at ", pos }
'
打印(为了可读性,在…
处对齐)
数字不同,因为它们指的是中间字符串中的位置,其中最后两个
...
Got |/| at 14
Got || at 15
您的单个正则表达式将“/”
转换为“/”
,出于类似的原因。正如其他人回答您的问题一样,我想我应该指出,您最初的“使用三重正则表达式”给出的正确结果实际上是有缺陷的。您的前缀和后缀都在字符串的开头或结尾处寻找零个或多个斜杠,而实际上您希望在因此,对于前缀,应该更正确地查找:-s,^([^/]),/\1,…。这将检查前面是否有斜杠,然后再加上找到的字符。@Sobrique我在我的帖子中添加了我认为比原来的口头陈述更清楚的内容。如果你看不到更改,请告诉你。
Got || at 0
Got |/| at 5
Got |///| at 11
Got |/| at 15
Got || at 15
s{( ^/* | /+ | /*$ )}{ say "Got |$1| at ", pos; q(/) }egx
...
Got |/| at 14
Got || at 15
$_ = '/' . (join '/', grep { /./ } split '/', $_) . '/' for @paths;