我在Perl中有两个关于Regexp::Common qw / URI /和Regex的问题。
我使用Regexp::Common qw/URI/
来解析字符串中的URI并删除它们。但是当URI在括号之间时我遇到了错误。
例如:(http://www.example.com)
错误是由')'引起的,当它尝试解析URI时,应用程序崩溃。所以我想到了两个问题:
)
字符之间写一个空格Regexp::Common qw/URI/
具有实现修复的功能。在我的代码中,我试图实现正则表达式,但应用程序冻结了。我试过的代码是:
use strict;
use Regexp::Common qw/URI/;
my $str = "Hello!!, I love (http://www.example.com)";
while ($str =~ m/\)/){
$str =~ s/\)/ \)/;
}
my ($uri) = $str =~ /$RE{URI}{-keep}/;
print "$uri\n";
print $str;
我想要的输出是:(http://www.example.com )
我不确定,但我认为问题出在$str =~ s/\)/ \)/;
顺便说一下,我有一个关于Regexp :: Common qw / URI /的问题。我有两种字符串类型:
http://www.example.com
http://www.example.com
aasdfasdfasdf 我想删除URI,如果它是最后一个组件(并保存)。如果没有,请保存,不要将其从文本中删除。
答案 0 :(得分:2)
您不必首先测试匹配项就能正确使用s///
运算符:如果字符串与搜索模式不匹配,则不会执行任何操作。
#!/usr/bin/perl
use strict; use warnings;
my $str = "Hello!!, I love (GOOGLE)";
$str =~ s/\)/ )/g;
print "$str\n";
在文本中正确检测URL的一般问题容易出错。请参阅示例Jeff's thoughts on this。
答案 1 :(得分:0)
my $str = "Hello!!, I love (GOOGLE)";
while ($str =~ m/)/){
$str =~ s/)/ )/;
}
此时你的程序进入无限循环。要了解原因,请尝试每次循环打印$ str的值。
my $str = "Hello!!, I love (GOOGLE)";
while ($str =~ m/)/){
$str =~ s/)/ )/;
print $str, "\n";
}
第一次打印“Hello !!,我爱(GOOGLE)”。然后再次评估while循环条件。你的字符串仍然匹配你的正则表达式(它仍然包含一个右括号),所以替换再次运行,这次打印出两个空格的“Hello !!,I love(GOOGLE)”。
所以它继续下去。每次循环循环时都会添加另一个空格,但每次仍有一个右括号时,都会运行另一个替换。
我能看到的最简单的解决方案是只匹配右括号(如果它前面有非空白字符)(使用\ S)。
my $str = "Hello!!, I love (GOOGLE)";
while ($str =~ m/\S)/){
$str =~ s/)/ )/;
print $str, "\n";
}
在这种情况下,循环只执行一次。
答案 2 :(得分:0)
为什么不在搜索中包含括号?如果URL总是被括起来,那么就像这样:
#!/usr/bin/perl
use warnings;
use strict;
use Regexp::Common qw/URI/;
my $str = "Hello!!, I love (http://www.google.com)";
my ($uri) = $str =~ / \( ( $RE{URI} ) \) /x;
print "$uri\n";
来自Regex :: Common的正则表达式可以用作更长正则表达式的一部分,它不必单独使用。另外我在正则表达式上使用'x'修饰符来允许空格,这样你就可以更清楚地看到发生了什么 - 带有反斜杠的括号被视为匹配的字符,那些没有定义要匹配的字符(大概就像是{-keep} - 我之前没用过。)
您还可以将括号设为可选,例如:
/ (?: \( ( $RE{URI} ) \) | ( $RE{URI} ) ) /
虽然这会产生两个匹配变量,一个是未定义的 - 所以需要像下面这样的东西:
my $uri = $1 || $2 || die "Didn't match a URL!";
可能有更好的方法来做到这一点,而且如果你不喜欢匹配括号,那么你可以简单地在第一个正则表达式中使括号可选(通过'?')...
要回答关于仅匹配行尾的URL的第二个问题 - 请查看正则表达式“锚点”,它可以强制匹配行的开头或结尾:^和$(或\ A和\ Z如果你愿意的话)。例如只匹配一行末尾的网址:
/$RE{URI}\Z/