这本来是一个我想问的问题,但在研究问题的细节时,我找到了解决方案,并认为其他人可能会感兴趣.
在Apache中,完整请求是双引号,并且内部的任何引号始终使用反斜杠进行转义:
1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\" foo=bat\" HTTP/1.0" 400 299 "-" "-" "-"
Run Code Online (Sandbox Code Playgroud)
我正在尝试构建一个匹配所有不同字段的正则表达式.我当前的解决方案总是停在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+|-)
Run Code Online (Sandbox Code Playgroud)
我想我也会从我的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
';';
Run Code Online (Sandbox Code Playgroud)
使用这个与URL不包含其他引号的简单情况工作正常:
1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\ foo=bat\ HTTP/1.0" 400 299 "-" "-" "-"
Run Code Online (Sandbox Code Playgroud)
现在我正试图获得支持,一次或多次出现\",但无法找到解决方案.使用regexpal.com到目前为止我已经想出了这个:
^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*"
Run Code Online (Sandbox Code Playgroud)
这里只有改变的部分:
# request uri
'"(.|\\(?="))*"' .
Run Code Online (Sandbox Code Playgroud)
但是,它太贪心了.它会吃掉所有东西直到最后",它应该只吃到第一个"没有先于a \.我也尝试\过在"我想要之前没有引入的要求,但它仍然吃到字符串的末尾(注意:我必须添加无关的\字符才能在PHP中使用):
# request uri
'"(.|\\(?="))*[^\\\\]"' .
Run Code Online (Sandbox Code Playgroud)
但是它击中了我:*?:如果在任何量词之后立即使用,+,?或{},使量词非贪婪(匹配最小次数)
# request uri
'"(.|\\(?="))*?[^\\\\]"' .
Run Code Online (Sandbox Code Playgroud)
完整的正则表达式:
^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*?[^\\]"\s+(\d+)\s+(\d+|-)
Run Code Online (Sandbox Code Playgroud)
2009年5月5日更新:
我在regexp中发现了一个小缺陷,因为解析了数百万行:它在包含双引号之前的反斜杠字符的行上中断.换一种说法:
...\\"
Run Code Online (Sandbox Code Playgroud)
将破坏正则表达式.Apache不会记录...\"但总会将反斜杠转义为\\,因此可以安全地假设在双引号之前有两个反斜杠字符.
任何人都知道如何使用正则表达式解决这个问题?
有用的资源:developer.mozilla.org和regexpal.com上的JavaScript Regexp文档
Gum*_*mbo 26
试试这个:
"(?:[^\\"]+|\\.)*"
Run Code Online (Sandbox Code Playgroud)
此正则表达式匹配双引号字符,后跟除了\和/ "或转义序列\?(其中?可以是任何字符)之后的任何字符的序列,后跟最后的双引号字符.该语法只是一个非捕获组.(?:expr)
| 归档时间: |
|
| 查看次数: |
24821 次 |
| 最近记录: |