可选捕获组

Optional capture 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"

我当前的正则表达式只匹配第二个

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

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

详情:

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

参见regex demo

现在,如果字符串中没有 ?,第 3 组将不会捕获任何内容,因为必须的 ?\s 是可选的 作为一部分序列.