我有一个用于从文本中提取URL的小Perl脚本:
#!/usr/bin/perl
while ( <STDIN> )
{
if ( /(http|ftp|https):\/\/([\w\-_]+(?:(?:\.[\w\-_]+)+))([\w\-\.,@?^=%&./~\+#]*[\w\-\@?^=%&/~\+#])?/ )
{
print;
}
}
当我在Textwrangler中搜索时,正则表达式工作正常,但是当我通过此脚本运行它时,我收到以下错误:
$ cat file.txt | perl myscript.pl
Unmatched [ in regex; marked by <-- HERE in m/(http|ftp|https)://([\w\-_]+(?:(?:\.[\w\-_]+)+))([ <-- HERE \w\-\.,@?^=%&./ at myscript.pl line 5.
答案 0 :(得分:5)
最后字符类中的/
也需要进行转义。您可以考虑使用/x
修饰符使其更具可读性,并使用不同的分隔符来避免“倾斜牙签”。另外,\w
类
已经包含下划线,并且字符类中的.
总是按字面意思匹配。
if (m{
(http|ftp|https)://
( [\w\-]+ (?: (?:\.[\w\-]+)+ ) )
(
[\w\-.,@?^=%&/~+#]*
[\w\-@?^=%&/~+#]
)?
}x
) {
print;
}
通过这样做,也很清楚最后两个字符类是不是真正的字符类:
这:/[&]*/
肯定会匹配&
,还会a&m&p
,ma
,pa
,&;
等等。
答案 1 :(得分:1)
由于/
是正则表达式分隔符,因此您需要转义正则表达式中存在的所有正斜杠。
(http|ftp|https):\/\/([\w\-_]+(?:(?:\.[\w\-_]+)+))([\w\-\.,@?^=%&.\/~\+#]*[\w\-\@?^=%&\/~\+#])?
我不知道你在角色类中想要实现这个&
是什么。此[&]
将匹配给定列表中的单个字符,无论它可能是&
还是a
还是m
还是p
,而不是整个&
}
答案 2 :(得分:0)
你可以使它更具可读性和可调试性,并且,我希望这可能会对你的问题有所了解。
while ( <STDIN> ) {
print if m{
( http | ftp | https )://
( [\w\-_]+ (?: (?:\.[\w\-_]+)+ ) )
(
[\w\-\.,@?^=%&./~\+#]*
[\w\-\@?^=%&/~\+#]
)?
}x;
另一方面,我会达到Regexp::Common::URI或URI::Find。试图修复这种模式似乎不是任何人的最佳用途。