很抱歉,我发现用我糟糕的英语很难表达这个问题。让我们直接来看一个简单的例子。
假设我们有一个主题字符串"apple:banana:cherry:durian"
。我们希望匹配主题,并使$1
、$2
、$3
和$4
分别变为"apple"
、"banana"
、"cherry"
和"durian"
。我使用的模式是^(\w+)(?::(.*?))*$
,$1
将是"apple"
。但是,$2
将是"durian"
而不是"banana"
。
因为要匹配的主题字符串不需要是4项,例如,它可以是"one:two:three"
,而$1
和$2
将分别是"one"
和"three"
。再次,中间项缺失。
在这种情况下,正确的模式是什么?顺便说一下,我将在C++代码中使用PCRE2,因此没有split
,这是一个Perl内置函数。谢谢。
2条答案
按热度按时间wgmfuz8q1#
如果输入包含严格意义上由
:
分隔的项目,如item1:item2:item3
,则可以使用正则表达式模式它匹配不是
:
的连续字符,因此是直到第一个:
的子字符串。这可能还需要捕获([^:]+)
,这取决于整体方法。如何使用它来获得 * 所有 * 这样的匹配取决于语言。在C++中,有不同的方法来实现这一点。使用std::regex_iterator
打印如预期。
还可以使用std::regex_search,即使它在第一个匹配时返回--通过迭代字符串,在每个匹配之后移动搜索开始
(With这个字符串和正则表达式我们不需要raw string literal,所以我在这里删除了它们。
†这个问题最初被标记为
perl
(没有c++),也在文本中提到了它;这个答案的原始版本提到Perl时//
是模式分隔符。/g
“修饰符”用于“global”,以查找所有匹配项。当这个表达式被绑定(=~)到一个带有目标字符串的变量,或者绑定到一个字符串文字,或者绑定到一个产生标量的表达式时,当在一个需要列表的上下文中使用时,整个表达式返回一个匹配列表。因此,它可以直接赋值给数组变量,其中list assignment本身提供上下文
(when这是字面上使用的,如图所示,然后捕获
()
是不需要的)赋值给一个数组提供了这个“列表上下文”。如果匹配是在“标量上下文”中使用的,在这种情况下需要一个值,比如在
if
测试的条件中或者被赋值给一个标量变量,那么返回一个true/false(通常是1
或''
,空字符串)。r55awzrz2#
重复捕获组将仅捕获最后一次迭代的值。相反,您可以使用
\G
锚来获得连续的匹配。如果整个字符串只能包含以冒号分隔的单词字符:
模式匹配:
(?:
非捕获组^
Assert字符串的开始(?=\w+(?::\w+)+$)
从当前位置Assert1+单词字符和1+重复:
和1+单词字符,直到字符串的结尾|
或\G(?!^):
在上一个匹配的末尾而不是开始处声明位置并匹配:
)
关闭非捕获组\K\w+
忽略目前匹配的内容,匹配1个以上单词字符Regex demo
要从字符串的开头开始只允许单词,并允许单词字符后的其他字符:
Regex demo