【问题标题】:Optional capture group可选捕获组
【发布时间】:2017-08-03 21:53:57
【问题描述】:

我需要解析一些 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"

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

【问题讨论】:

  • 你想在上面的输入中捕捉什么?
  • @AkashKC GET 参数。但前提是它们存在。如果它们不存在,它应该只是一个空组

标签: java regex regex-group


【解决方案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 是可选的作为序列的一部分。 p>

【讨论】:

  • 但我希望 GET 参数在一个单独的组中
  • 你的也可以通过(GET|POST)\s(.*)\sHTTP\/(\d\.\d)实现
  • 好的,使用懒点。
  • @WiktorStribiżew:(?:(\?.*)\s)? 是什么意思?
  • 只要'(GET|POST)\\s(.*)(\\??.*)\\sHTTP\\/(\\d\\.\\d)' 应该可以工作(加上一个额外的?)。
猜你喜欢
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2018-07-19
  • 2015-12-04
  • 1970-01-01
相关资源
最近更新 更多