使用 Regex Group 从 CURL 获取个人 headers

Get individual headers from CURL with Regex Group

我正在尝试使用 RegEx 组捕获获取 bash CURL 命令的所有 header,但我遇到了一个问题,它只是获取了所有 header 在一组(和另一组,我不完全知道为什么会这样)。

bash:

curl '<url>' -H 'origin: <url>' -H 'accept-endocing: <...>' -H 'accept-language: <...>' <continues with more headers> --data '<...>'

并与其他 header 一起继续。

代码:

var rawBash = RawBash.Text;
var headerPattern = @"\-H[\s][\']{1}(.+)[\']{1}";
var headers = Regex.Match(rawBash, headerPattern);

我已经 tested the pattern here 并且显示“11 个捕获”,'correctly' 表示我想要捕获的组,但是当我调试代码时它指示捕获了 2 个组:

  1. 以第一个“-H”开头的整个 CURL
  2. 以"origin:"
  3. 开头的整个CURL

发生了什么事?我猜 Regex 正在使用 (.+) 而不是在它到达 [\']{1} 时终止,因为 ' 匹配 (.+)...但是我如何让它捕获每个人header在一组?

我尝试通读了一些 C# RegEx tutorials/descriptions,但我无法找到我正在寻找的内容(或用正确的措辞描述我正在寻找的内容).

编辑: 发帖几秒钟后我就有了尝试这种模式的想法:

var headerPattern = @"\-H[\s][\']{1}([^\']+)[\']{1}";

请注意该组现在是 ([^\']+) 而不是 (.+)。它现在可以正常工作了。

此外,我正在使用 Regex.Match(...),它应该是 Regex.Matches(...) 来获取所有匹配项。

但我想这个问题仍然存在;某人如何在某个点终止组捕获?我记得一位朋友在我认为类似的情况下使用了术语 forward lookup,但我不知道如何实施。

您看到的是贪婪与惰性(或 non-greedy)匹配的效果。

贪心匹配会匹配尽可能多的字符 惰性匹配只会匹配所需数量的字符。

在你的原始模式中(.+)是一个或多个或任何字符的贪婪匹配。所以它会从你的第一个 -H ' 到最后一个 '

你把它改成 ([^\']+) 也是贪婪的,但是它提前终止了,因为它不匹配任何字符,它唯一匹配的字符不是 '

您可以将 *+ 直接添加到 ? 后改为懒惰。

我对你的 header 匹配器的解决方案是(假设你的示例字符串相当代表一致的格式)。

\-H\s+\'(.+?)\'

您的朋友指的是正面预测。这期待在字符串中获得成功的匹配,但是它匹配的不是完整匹配字符串的一部分。语法是 (?=...)。还有一个负向前瞻 (?!...) 和正负向后回顾,分别为 (?<=...)(?<!...)。应谨慎使用它们,因为它们在较长的字符串上效率真的很低。

例如采用以下 2 个字符串:

regex isnt always the right answer|this will match

regex isnt always the right answer|this will not

如果我使用以下模式:

regex (is.*) always (the right answer(?=.*this will match))

第一个字符串的结果是:

Full match  0-34    `regex isnt always the right answer`
Group 1.    6-10    `isnt`
Group 2.    18-34   `the right answer`

并且完全不会匹配第二个。