对于我正在开发的应用程序,我需要一个 Perl 脚本,它循环遍历大量 CSV 文件并确保每一行都包含有效的 URI。我之前已经问过一个关于解析 CSV 文件的问题,并且我已经开始使用Text::CSV
让我的生活变得更轻松。现在我面临确保 URI 有效的问题。
由于我的应用程序的性质,URI 不需要采用完整的形式
protocol://username:[email protected]/request?vars=values
相反,我只对此的请求部分感兴趣。对于一般网站,这将是之后的任何内容.com
, .edu
, etc.
我目前有以下 Perl 脚本:
if($_ !~ /^(?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*$/i){
print "Invalid URL format";
exit;
} else {
/* stuff */
}
正则表达式应该相当简单。请求允许包含一小组符号中的一个([a-z0-9-._~!$&'()*+,;=:/?@]
) 或者它可能包含百分号 (%
) 后跟两个十六进制数字。这些模式中的任何一个都可以无限地重复。
当我运行此脚本时,出现以下错误:
Number found where operator expected at ./301rules.pl line 58, near "%[0"
(Missing operator before 0?)
Bareword found where operator expected at ./301rules.pl line 58, near "9A"
(Missing operator before A?)
Bareword found where operator expected at ./301rules.pl line 58, near "$/i"
(Missing operator before i?)
syntax error at ./301rules.pl line 58, near "%[0"
很明显,我的正则表达式中的某些内容需要转义,但我不确定是什么。我尝试着逃避every创建以下正则表达式的可能符号:
if($_ !~ /^(?:[a-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\/\?\@]|%[0-9A-F]{2})*$/i){
然而,当我这样做时,它只是允许every通过测试的字符串,即使是我知道无效的字符串,例如te%st
or é
那么有没有人有 Perl 正则表达式的经验并且知道我需要转义什么以及我不应该转义什么?对于 19 个不同的符号,我不想尝试所有 2^19 = 524288 种可能性。
编辑-投票结束。我发现这个问题实际上就存在于这个循环之上,尽管我还不完全明白为什么。
I had:
if( $_ == "" ){
next;
}
/* regex conditional from above */
无论出于何种原因,它不断评估为 true 并进入下一次迭代,尽管显然有数据存储在$_
。我会弄清楚为什么会这样,但目前正则表达式可以很好地处理所有转义的内容。