包含转义引号的引号之间匹配的正则表达式

时间:2009-03-29 08:59:42

标签: regex pcre

这最初是我想问的一个问题,但在研究问题的详细信息时,我找到了解决方案,并认为其他人可能对此感兴趣。

在Apache中,完整请求是双引号,并且内部的任何引号总是使用反斜杠进行转义:

1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\" foo=bat\" HTTP/1.0" 400 299 "-" "-" "-"

我正在尝试构建一个匹配所有不同字段的正则表达式。我的当前解决方案始终在GET / POST后的第一个引号上停止(实际上我只需要包括传输大小的所有值):

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"[^"]+"\s+(\d+)\s+(\d+|-)

我想我也会从PHP源代码中提供我的解决方案和更好的格式化解决方案:

$sPattern = ';^' .
    # ip address: 1
    '(\d+\.\d+\.\d+\.\d+)' .
    # ident and user id
    '\s+[^\s]+\s+[^\s]+\s+' .
    # 2 day/3 month/4 year:5 hh:6 mm:7 ss +timezone
    '\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]' .
    # whitespace
    '\s+' .
    # request uri
    '"[^"]+"' .
    # whitespace
    '\s+' .
    # 8 status code
    '(\d+)' .
    # whitespace
    '\s+' .
    # 9 bytes sent
    '(\d+|-)' .
    # end of regex
    ';';

在URL不包含其他引号的简单情况下使用它可以正常工作:

1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\ foo=bat\ HTTP/1.0" 400 299 "-" "-" "-"

现在,我正在尝试为其中的一个或多个\"提供支持,但无法找到解决方案。使用regexpal.com到目前为止我已经想出了这个:

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*"

这里只是改变的部分:

    # request uri
    '"(.|\\(?="))*"' .

然而,它太贪心了。它会吃掉所有内容,直到最后",它应该只吃到第一个"前面没有\。我还尝试在我想要的\之前引入了"的要求,但它仍然吃到字符串的末尾(注意:我必须添加无关的\个字符才能生成这项工作在PHP):

    # request uri
    '"(.|\\(?="))*[^\\\\]"' .

然后它击中了我: * ? :如果在任何量词,+,?或{}之后立即使用,则使量词非贪婪(匹配最小次数)

    # request uri
    '"(.|\\(?="))*?[^\\\\]"' .

完整的正则表达式:

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*?[^\\]"\s+(\d+)\s+(\d+|-)

2009年5月5日更新:

我在正则表达式中发现了一个小缺陷,因为解析了数百万行:它在双引号之前的包含反斜杠字符的行上中断。换句话说:

...\\"

将打破正则表达式。 Apache不会记录...\",但总会将反斜杠转义为\\,因此可以安全地假设在双引号之前有两个反斜杠字符。

任何人都知道如何使用正则表达式解决这个问题?

有用资源:the JavaScript Regexp documentation at developer.mozilla.orgregexpal.com

1 个答案:

答案 0 :(得分:26)

试试这个:

"(?:[^\\"]+|\\.)*"

此正则表达式匹配双引号字符,后跟除\"之外的任何字符或转义序列\ α < / em>(其中 α 可以是任何字符),后跟最后的双引号字符。 (?: expr )语法只是一个非捕获组。