我有一个正则表达式定义跟随匹配http urls
,任何人都可以帮助用英语解释?
^/foo/.*(?<!\.css|\.js|\.jpg)$
目录或目录下的任何文件或目录/foo
不是css
,js
或jpg
文件。
^ start of string anchor
/foo/ literal "/foo/"
.* any number of characters
(?<!...) match from here backwards must fail:
\. dot
css literal "css"
| or
$ end of string anchor
因此,字符串的开头/foo/
,可能是其他一些字符,然后字符串结束 - 但就在之前,不能是.css
,.js
或.jpg
。
编辑:为固执而道歉。对于大多数引擎,包括 Perl,它确实是一个无效的正则表达式。原因是,负后视必须有固定的宽度;并且这个lookbehind可以是四个字符(在 or 的情况下.jpg
).css
或三个字符(.js
)。解决方法是在后视中插入一个额外的“匹配任何东西”,以便宽度始终为四:
^/foo/.*(?<!\.css|.\.js|\.jpg)$
有了它,它可以工作:
perl -e 'print "/foo/bar" =~ m[^/foo/.*(?<!\.css|.\.js|\.jpg)$];'
=> 1
OP:您对 regexpal.com 的问题在于他们测试 JavaScript 正则表达式,而这些正则表达式根本没有实现否定的后视。正则表达式方言在细节上有所不同。
您的模式旨在与以下内容匹配:
m{^/foo/} && !m{\.(?:css|js|jpg)\z}
这更具可读性,我不需要解释它。与您的模式不同,它还具有实际编译的优势。
>perl -c -e"m{^/foo/.*(?<!\.css|\.js|\.jpg)$}"
Variable length lookbehind not implemented in regex m/^/foo/.*(?<!\.css|\.js|\.jpg)$/ at -e line 1.
它匹配任何字符串
/foo/
.css
,.js
或.jpg
因此,它匹配根目录foo
(直接或作为子目录)下的任何不是 CSS、JS 或 JPG 的文件。
使用 学习正则表达式YAPE::Regex::Explain
。检查以下代码:
#!/usr/bin/perl -w
use strict;
use YAPE::Regex::Explain;
my $regex = '^/foo/.*(?<!\.css|\.js|\.jpg)$';
print YAPE::Regex::Explain->new($regex)->explain();
输出:
The regular expression:
(?-imsx:^/foo/.*(?<!\.css|\.js|\.jpg)$)
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
^ the beginning of the string
----------------------------------------------------------------------
/foo/ '/foo/'
----------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
(?<! look behind to see if there is not:
----------------------------------------------------------------------
\. '.'
----------------------------------------------------------------------
css 'css'
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
\. '.'
----------------------------------------------------------------------
js 'js'
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
\. '.'
----------------------------------------------------------------------
jpg 'jpg'
----------------------------------------------------------------------
) end of look-behind
----------------------------------------------------------------------
$ before an optional \n, and the end of the
string
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------