regex - 使用 Perl 正则表达式确定 URI 是否有效

标签 regex perl escaping

对于我正在开发的应用程序,我需要一个 Perl 脚本来遍历大量 CSV 文件并确保每一行都包含一个有效的 URI。我之前已经问过一个关于解析 CSV 文件的问题,并且我已经开始使用 Text::CSV 让我的生活变得更轻松。现在我遇到了确保 URI 有效的问题。

由于我的应用程序的性质,URI 不需要采用完整形式

protocol://username:password@domain.extension/request?vars=values

我只对请求部分感兴趣。对于一般网站,可以是 .com.edu 等之后的任何内容。

我目前有以下 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"

很明显,我的正则表达式中的某些内容需要转义,但我不确定是什么。我尝试转义每个 可能的符号以创建以下正则表达式:

if($_ !~ /^(?:[a-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\/\?\@]|%[0-9A-F]{2})*$/i){

然而,当我这样做时,它只允许每个 字符串通过测试,即使是我知道无效的字符串,例如 te%sté

那么有没有人有使用 Perl 正则表达式的经验并且知道我需要转义什么以及不应该转义什么?有 19 种不同的符号,我不想尝试所有 2^19 = 524288 种可能性。

编辑 - 投票结束。我发现这个问题实际上就存在于这个循环之上,尽管我还不完全明白为什么。

我有:

if( $_ == "" ){
    next;
}
/* regex conditional from above */

无论出于何种原因,尽管 $_ 中显然存储了数据,但它一直评估为 true 并进入下一次迭代。我会弄清楚这是为什么,但现在正则表达式可以正常处理所有转义的内容。

最佳答案

URI module 的文档中我发现了以下内容:

PARSING URIs WITH REGEXP

As an alternative to this module, the following (official) regular expression can be used to decode a URI:

    my($scheme, $authority, $path,
    $query, $fragment) =   $uri =~
    m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;

The URI::Split module provides the function uri_split() as a readable alternative.

但我认为Regexp::Common::URI可能是 HTTP URI 语法验证的理想解决方案。

use Regexp::Common qw /URI/;
while (<>) {
    /$RE{URI}{HTTP}/  and  print "Contains an HTTP URI.\n";
}

任何由 Damian 编写并由 Abigail 维护的东西都必须是灵感、伟大、疯狂或以上所有。 (我的意思是怀着最高的敬意)。

关于regex - 使用 Perl 正则表达式确定 URI 是否有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6449015/

相关文章:

perl - Catalyst 事件循环一次仅到达一个客户端

regex - 可以匹配正值和负值的 Perl 正则表达式

c++ - 加号转义 C++

regex - 如何仅在 diff block 中搜索 - gvim diff

regex - 正则表达式工具(如 RegexBuddy)是个好主意吗?

javascript - 在 node.js 的正则表达式中指定或

java - 正则表达式 Java 错误

perl - 存储时间序列数据,无需数据库

java - 如何为模式编译转义方括号?

java -\n 不会在 AlertDialog 中生成换行符