可选的捕获组

时间:2017-03-13 18:43:55

标签: java regex regex-group

我需要解析一些HTTP请求,现在想要解析GET参数。

我现在的正则表达式是

(GET|POST)\s(.*)(\?.*)\sHTTP\/(\d\.\d)

我想匹配以下内容:

"GET /page.html HTTP/1.1"
  => group1: "GET" group2: "/page.html" group3: "" group4: "1.1"

"GET /page.html?param1=foo&param2=bar HTTP/1.1"
  => group1: "GET" group2: "/page.html" group3: "param1=foo&param2=bar" group4: "1.1"

我目前的正则表达式仅匹配第二个

1 个答案:

答案 0 :(得分:2)

使用可选的非捕获组包装第三个捕获组,并在第二个捕获组中使用惰性*?量词,以尽可能少地将字符匹配到第2组(对于匹配查询参数的第3组,可以抓取那些数据如果存在):

(GET|POST)\s(.*?)(?:(\?.*)\s)?HTTP\/(\d\.\d)
               ^ ^^^^^^^^^^^^^

<强>详情:

  • (GET|POST) - 第1组:GETPOST子字符串
  • \s - 空白
  • (.*?) - 第2组:任何0+字符,尽可能少(如果查询字符串存在,则将查询字符串中的所有参数传递给下一个捕获组)
  • (?:(\?.*)\s)? - 可选(1或0次)非捕获组匹配:
    • (\?.*) - 第3组捕获?,尽可能多的0个字符,直到最后......
    • \s - witespace
  • HTTP\/ - HTTP/文字字符序列
  • (\d\.\d) - 第4组捕获数字.和数字。

请参阅regex demo

enter image description here

现在,如果字符串中没有?,则第3组将不会捕获任何内容,因为强制性?\s是可选的作为序列的一部分< / em>的