逻辑或不在正则表达式中工作

时间:2014-07-19 17:49:30

标签: regex regex-alternation

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

-- "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])) 

我希望得到GETPOST之后的部分,直到第一次出现空格' '或问号'?'

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

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

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

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

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

请有人告诉我我错在哪里吗?

3 个答案:

答案 0 :(得分:4)

  

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

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

要合并它们,您需要说:所有既不是问号也不是空格的字符:

[^?\s]+

使用你曾经使用过的OR,它只是尝试了第一个([^\?]+ - 包括空格),这是成功的,如果是第一个,它会回溯并尝试[^\s]+(包括问号)没有工作。

答案 1 :(得分:3)

从索引2获取匹配的组

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

这是DEMO

模式说明:

  \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

答案 2 :(得分:1)

以下正则表达式仅匹配GETPOST之后的字符串,后跟空格或?符号。

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

DEMO

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

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

DEMO

<强>解释

(?<=                     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