英文:
regex101 - match all occurrences of a string only in the first line where it is found
问题
在regex101网站上,我有以下文本:
text3 text3 text3 text3 text3 text3
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
我想匹配所有的text2
,但只在第一行中找到它:
text3 text3 text3 text3 text3 text3
text1 **text2** text1 **text2** text1 **text2**
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
我该如何实现这个?
英文:
In regex101 site I have the text:
text3 text3 text3 text3 text3 text3
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
I want to match all text2
but only in the first line where it is found:
text3 text3 text3 text3 text3 text3
text1 **text2** text1 **text2** text1 **text2**
text1 text2 text1 text2 text1 text2
text1 text2 text1 text2 text1 text2
How do I get this?
答案1
得分: 3
/(?:^.*?|\G[^\r\n]*?)\Ktext2/gs
/(?:^[\s\S]*?|\G[^\r\n]*?)\Ktext2/g
/(?:\A[\s\S]*?|\G[^\r\n]*?)\Ktext2/gm
英文:
You can do this with regex flavours like PCRE, which support an end-of-match token (\G
) and can be set to single line matching (/s
). The idea is to match the first target by anchoring to the beginning of the line while consuming as few characters as possible (^.*?
) and then to allow further matches only at the end of previous matches, while excluding line breaks in procuring them (\G[^\r\n]*?
). See regex demo.
An expression to do that could look like this:
/(?:^.*?|\G[^\r\n]*?)\Ktext2/gs
\K
is simply used to cut out the preceeding part of matches from the result to avoid using capturing groups for singling out text2
.
To cover other aspects of line break/position matching, if you want to drop the single-line modifier (/s
), in which case .
ceases to match new-line characters, you can use a class that also matches line breaks, like [\s\S]*?
, instead of .*?
to get the initial match. See demo.
/(?:^[\s\S]*?|\G[^\r\n]*?)\Ktext2/g
If you want to use the multi-line modifier /m
specifically, in which case the caret ^
now matches at the beginning of every line, you'll have to use the anchor for the beginning of string \A
instead to match the initial target. See demo.
/(?:\A[\s\S]*?|\G[^\r\n]*?)\Ktext2/gm
答案2
得分: 2
你可以使用具有前瞻捕获组的技巧来实现(当然要禁用全局标志)。
你的正则表达式如下:
text2(?=(?:.*?(text2))*)
演示请点击这里
请注意,如果你有两个以上的分开匹配元素,你需要选择.NET结束,因为只有它允许对同一组进行多次捕获。
英文:
You can do it using trick with capturing groups inside of lookahead (and disabled global flag of course).
Your regex would this:
text2(?=(?:.*?(text2))*)
Demo here
Notice that if you have more than two separate matching elements, you'll need to select .Net ending, as only it will allow multiple captures for the same group.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论