【发布时间】:2018-06-22 09:40:34
【问题描述】:
上下文。我正在开发一个 Lexer/Tokenizing 引擎,它将使用正则表达式作为后端。词法分析器接受规则,这些规则定义了标记类型/ID,例如
<identifier> = "\\b\\w+\\b".
正如我所设想的,要进行基于正则表达式匹配的标记化,正则表达式定义的所有规则都包含在捕获组中,并且所有组都由 OR 分隔。
在执行匹配时,我们生成的每个匹配必须有一个与之匹配的捕获组的索引。我们使用这些 ID 将匹配项映射到令牌类型。
那么这个问题的问题就出现了——如何获取组的ID?
Similar question 在这里,但它没有为我的具体问题提供解决方案。
正是我的问题here,但它在 JS 中,我需要 C/C++ 解决方案。
假设我有一个正则表达式,由 OR 分隔的捕获组组成:
(\\b[a-zA-Z]+\\b)|(\\b\\d+\\b)
匹配整数或字母词。
我的问题要求正则表达式子匹配匹配的捕获组的索引是已知的,例如匹配字符串时
foo bar 123
将完成 3 次迭代。每次迭代匹配的组索引为0 0 1,因为前两个匹配匹配第一个捕获组,最后一个匹配匹配第二个捕获组。
我知道在标准的 std::regex 库中这并不完全可能(regex_token_iterator 不是解决方案,因为我不需要跳过任何匹配项)。
我对@987654329@ 或 PCRE 正则表达式库了解不多。
完成这项任务的最佳方法是什么?使用哪个库和方法?
【问题讨论】:
-
遍历所有匹配项,直到找到一个非空匹配项,即匹配项。
-
@Barmar 不是。
std::regex结果将只是一个非空子匹配数组。例如。当第 6 组是唯一匹配的组时,std::match_results结果数组将包含 2 个条目:整个正则表达式匹配,以及第 6 组的子匹配,它位于数组的索引 1 处,因为它是第一个匹配。我们无法从中获取正则表达式中组的索引6。 -
你确定吗?在所有其他语言中,组是根据 RE 编号的,而不是它们是否匹配。您需要能够引用特定匹配项,而不必担心之前的组是否匹配。这似乎使捕获组无法在 C++ 中可靠地使用。
-
或者,单独运行这些正则表达式。
-
which would be at index 1 of the array- 这绝不是真的!匹配对象在匹配之前根据定义的捕获组的数量预分配。当您通过索引match[group number]取消引用 match_object 时访问的实际 sub_match 对象返回指向存在于其他数组中的 sub_match 对象的指针。如果在取消引用 match_object 时它不包含指针,则它是 NULL。因此,您所做的是迭代组数,取消引用 match_object。如果它不是NULL,那就是匹配的那个。确保未设置 no-subs。
标签: c++ regex tokenize lexer capturing-group