1

我正在处理一个大日志文件,其条目如下:

-- "GET <b>/fss-w3-mtpage.php</b> HTTP/1.1" 200 0.084 41 "-" "c110bc/1.0" 127.0.0.1:25001  0.084

-- "GET <b>/m/firstpage/Services/getAll</b>?ids=ABCVDFDS,ASDASBDB,ASDBSA&requestId=091fa2b4-643e-4473-b6d8-40210b775dcf HTTP/1.1" 200

-- POST <b>/lastpage/Services/getAll</b>?ids=ABCVDFDS,ASDASBDB,ASDBSA&requestId=091fa2b4-643e-4473-b6d8-40210b775dcf HTTP/1.1" 200

我想提取上面示例中加粗的部分。这是我为上述内容编写的正则表达式

.*(POST|GET)\s+(([^\?]+)|([^\s])) 

我想得到在第一次出现空格或问号之前GET或之后的部分。POST' ''?'

问题
正则表达式后面部分的逻辑 OR 不起作用。如果我只使用

.*(POST|GET)\s+([^\?]+)    

我得到了正确的部分,即从 GET 或 POST 直到第一个问号'?'。同样,如果我使用

.*(POST|GET)\s+([^\s]+)    

我得到了正确的部分,即从 GET 或 POST 到第一个空格' ')。

请问谁能告诉我哪里错了?

4

3 回答 3

4

随着[^\?]+我得到正确的部分直到第一个问号,
随着[^\s]+我得到正确的部分直到第一个空格

因为这些字符类意味着:所有没有问号的字符,或者:所有没有空格的字符。

要将它们组合起来,您想说:所有既不是问号也不是空格的字符:

[^?\s]+

使用您使用的 OR,它只是尝试了第一个([^\?]+- 包括空格),它成功了,如果第一个不起作用,它会回溯并尝试[^\s]+(包括问号)。

于 2014-07-19T17:54:32.127 回答
3

从索引 2 中获取匹配组

\b(POST|GET)\s+([^?\s]+)

这是演示

图案说明:

  \b                       the word boundary

  (                        group and capture to \1:
    POST                     'POST'
   |                        OR
    GET                      'GET'
  )                        end of \1

  \s+                      whitespace (\n, \r, \t, \f, and " ") (1 or more times)

  (                        group and capture to \2:

    [^?\s]+                  any character except: '?', whitespace
                             (\n, \r, \t, \f, and " ") (1 or more times)

  )                        end of \2
于 2014-07-19T17:52:44.533 回答
1

下面的正则表达式将仅匹配紧随 toGETPOST后跟空格或?符号的字符串。

(?<=GET |POST )\s*.*?(?= |\?)

演示

您可以使用捕获组(),以捕获匹配的字符串。

(?<=GET |POST )\s*(.*?)(?= |\?)

演示

解释:

(?<=                     look behind to see if there is:
  GET                      'GET '
 |                        OR
  POST                     'POST '
)                        end of look-behind
\s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                         more times)
(                        group and capture to \1:
  .*?                      any character except \n (0 or more
                           times)
)                        end of \1
(?=                      look ahead to see if there is:
                           ' '
 |                        OR
  \?                       '?'
)                        end of look-ahead
于 2014-07-19T18:21:53.047 回答