0

我有一个正则表达式定义跟随匹配http urls,任何人都可以帮助用英语解释?

^/foo/.*(?<!\.css|\.js|\.jpg)$
4

4 回答 4

6

目录或目录下的任何文件或目录/foo不是css,jsjpg文件。

^        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 正则表达式,而这些正则表达式根本没有实现否定的后视。正则表达式方言在细节上有所不同。

于 2013-01-12T06:08:43.133 回答
4

您的模式旨在与以下内容匹配:

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.
于 2013-01-12T06:19:38.050 回答
3

它匹配任何字符串

  1. 以一个开头/foo/
  2. 随随便便
  3. 不以.css,.js.jpg

因此,它匹配根目录foo(直接或作为子目录)下的任何不是 CSS、JS 或 JPG 的文件。

于 2013-01-12T06:09:01.497 回答
2

使用 学习正则表达式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
----------------------------------------------------------------------
于 2013-01-12T06:33:53.750 回答