非捕获子程序
Non-capturing subroutines
我想知道是否可以调用子例程但不捕获该调用的结果。
例如,假设我想递归匹配并捕获一个平衡的括号{}结构,例如
{dfsdf{sdfdf{ {dfsdf} }}dfsf}
我可以使用这个正则表达式:
(^(?'nest'\{(?>[^{}]|(?&nest))*\}))
第一组是我要拍的
但是我对'nest'的定义是:
(?'nest' ... )
和我对 'nest' 子例程的递归调用:
(?&nest)
也在捕获组。我想让我的正则表达式更有效率并通过不捕获这些组来节省 space 。有什么办法吗?
编辑:我预计不可能不捕获子例程定义,因为它的模式需要被捕获以用于其他地方。
编辑2:
我正在用 boost::regex 以及记事本++正则表达式测试这个正则表达式。他们实际上似乎定义了不同的捕获组,这对我来说很奇怪。我的印象是他们都默认使用 Perl 正则表达式。
无论如何,在问这个问题时,我有正则表达式:
^\w+\s+[^\s]+\s+(?'header'(?'nest'\{(?>[^{}]|(?&nest))*\}))(?>\s+[^\s]+){5}\s+(?'data'(?>\{(?>[^{}]|(?&nest))*\}))\s+(?'class'(?>\{(?>[^{}]|(?&nest))*\}))
我后来意识到它包含 'nest' 已经封装的不必要的字符。我现在有:
^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))
当我执行替换语句时,Notepad++ 为我提供了 3 个捕获组
\1: \n \2: \n 3: \n 4:
它告诉我“第 1 个已被替换,下一个未找到”。替换在 4: 之后没有文本,让我相信第 4 个捕获组不存在。
然而 boost::regex_匹配 returns 具有 6 个位置的对象:
0:比赛的元数据
1:整场比赛
2:整场比赛
3: 来自记事本++的group1
4: 来自记事本++的group2
5: 来自记事本++的group3
我仍在尝试发送位置 1 和 2。
edit3
我又误解了一块拼图...
boost::cmatch.m_subs[i] != boost::cmatch[i]
我以为他们是平等的。经过更多调试后,事实证明索引到对象的工作方式与文档中所说的完全一样。但我错误地认为该对象将包含一个反映 boost::cmatch[i] 返回内容的结构。 boost::cmatch[i] 似乎首先从 m_subs 中删除所有匹配 == false 的条目。其余条目与 boost::cmatch[i] returns 对齐。
子例程调用是一种递归 子模式 的机制。正则表达式引擎必须知道要递归哪个组,这就是为什么它需要它的 ID(如果该组是 编号 )或名称(如果它是一个命名组,就像您的情况一样) ). 非捕获组 不要存储对这些组模式的引用,因此,您不能在子例程调用中引用它们。
在子例程调用中不使用捕获组的唯一方法是使用 整个模式的快捷方式、(?R)
。但是,当您需要递归模式的 部分 时,这不是一个选项(在您的情况下,您想要匹配字符串的开头,并且只在 ^
.
放入 (?(DEFINE).) 构造中的任何子例程都不会捕获任何内容。
如果你只是想避免被捕获,可以这样做
https://regex101.com/r/aT4TlM/1
注意 -
Subpattern definition construct (?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
May only be used to define functions. No matching is done in this group.
^(?&nest)(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
因为你有那个 BOS 锚 ^
这是唯一的方法。
IE。 (?R)
不是一个选项。
展开
^
(?&nest)
(?(DEFINE)
(?'nest' # (1 start)
\{
(?>
[^{}]
| (?&nest)
)*
\}
) # (1 end)
)
输出
** Grp 0 - ( pos 0 , len 29 )
{dfsdf{sdfdf{ {dfsdf} }}dfsf}
** Grp 1 [nest] - NULL
指标
----------------------------------
* Format Metrics
----------------------------------
Atomic Groups = 1
Capture Groups = 1
Named = 1
Recursions = 2
Conditionals = 1
DEFINE = 1
Character Classes = 1
回复:Edit2
这个正则表达式 ^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))
格式化为仅包含 3 个组时可以看到。
^ \w+ \s+ [^\s]+ \s+
(?'nest' # (1 start)
\{
(?>
[^{}]
| (?&nest)
)*
\}
) # (1 end)
(?> \s+ [^\s]+ ){5}
\s+
( (?&nest) ) # (2)
\s+
( (?&nest) ) # (3)
你想用这个做什么?
我想知道是否可以调用子例程但不捕获该调用的结果。
例如,假设我想递归匹配并捕获一个平衡的括号{}结构,例如
{dfsdf{sdfdf{ {dfsdf} }}dfsf}
我可以使用这个正则表达式:
(^(?'nest'\{(?>[^{}]|(?&nest))*\}))
第一组是我要拍的
但是我对'nest'的定义是:
(?'nest' ... )
和我对 'nest' 子例程的递归调用:
(?&nest)
也在捕获组。我想让我的正则表达式更有效率并通过不捕获这些组来节省 space 。有什么办法吗?
编辑:我预计不可能不捕获子例程定义,因为它的模式需要被捕获以用于其他地方。
编辑2:
我正在用 boost::regex 以及记事本++正则表达式测试这个正则表达式。他们实际上似乎定义了不同的捕获组,这对我来说很奇怪。我的印象是他们都默认使用 Perl 正则表达式。
无论如何,在问这个问题时,我有正则表达式:
^\w+\s+[^\s]+\s+(?'header'(?'nest'\{(?>[^{}]|(?&nest))*\}))(?>\s+[^\s]+){5}\s+(?'data'(?>\{(?>[^{}]|(?&nest))*\}))\s+(?'class'(?>\{(?>[^{}]|(?&nest))*\}))
我后来意识到它包含 'nest' 已经封装的不必要的字符。我现在有:
^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))
当我执行替换语句时,Notepad++ 为我提供了 3 个捕获组
\1: \n \2: \n 3: \n 4:
它告诉我“第 1 个已被替换,下一个未找到”。替换在 4: 之后没有文本,让我相信第 4 个捕获组不存在。
然而 boost::regex_匹配 returns 具有 6 个位置的对象:
0:比赛的元数据
1:整场比赛
2:整场比赛
3: 来自记事本++的group1
4: 来自记事本++的group2
5: 来自记事本++的group3
我仍在尝试发送位置 1 和 2。
edit3
我又误解了一块拼图...
boost::cmatch.m_subs[i] != boost::cmatch[i]
我以为他们是平等的。经过更多调试后,事实证明索引到对象的工作方式与文档中所说的完全一样。但我错误地认为该对象将包含一个反映 boost::cmatch[i] 返回内容的结构。 boost::cmatch[i] 似乎首先从 m_subs 中删除所有匹配 == false 的条目。其余条目与 boost::cmatch[i] returns 对齐。
子例程调用是一种递归 子模式 的机制。正则表达式引擎必须知道要递归哪个组,这就是为什么它需要它的 ID(如果该组是 编号 )或名称(如果它是一个命名组,就像您的情况一样) ). 非捕获组 不要存储对这些组模式的引用,因此,您不能在子例程调用中引用它们。
在子例程调用中不使用捕获组的唯一方法是使用 整个模式的快捷方式、(?R)
。但是,当您需要递归模式的 部分 时,这不是一个选项(在您的情况下,您想要匹配字符串的开头,并且只在 ^
.
放入 (?(DEFINE).) 构造中的任何子例程都不会捕获任何内容。
如果你只是想避免被捕获,可以这样做
https://regex101.com/r/aT4TlM/1
注意 -
Subpattern definition construct
(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
May only be used to define functions. No matching is done in this group.
^(?&nest)(?(DEFINE)(?'nest'\{(?>[^{}]|(?&nest))*\}))
因为你有那个 BOS 锚 ^
这是唯一的方法。
IE。 (?R)
不是一个选项。
展开
^
(?&nest)
(?(DEFINE)
(?'nest' # (1 start)
\{
(?>
[^{}]
| (?&nest)
)*
\}
) # (1 end)
)
输出
** Grp 0 - ( pos 0 , len 29 )
{dfsdf{sdfdf{ {dfsdf} }}dfsf}
** Grp 1 [nest] - NULL
指标
----------------------------------
* Format Metrics
----------------------------------
Atomic Groups = 1
Capture Groups = 1
Named = 1
Recursions = 2
Conditionals = 1
DEFINE = 1
Character Classes = 1
回复:Edit2
这个正则表达式 ^\w+\s+[^\s]+\s+(?'nest'\{(?>[^{}]|(?&nest))*\})(?>\s+[^\s]+){5}\s+((?&nest))\s+((?&nest))
格式化为仅包含 3 个组时可以看到。
^ \w+ \s+ [^\s]+ \s+
(?'nest' # (1 start)
\{
(?>
[^{}]
| (?&nest)
)*
\}
) # (1 end)
(?> \s+ [^\s]+ ){5}
\s+
( (?&nest) ) # (2)
\s+
( (?&nest) ) # (3)
你想用这个做什么?