如果模式重复两次(非连续),则匹配两个模式,正则表达式。

3

我有三个值要匹配:foobar123。但我只想在它们可以匹配两次的情况下匹配它们。

在下面这行中:

foo;bar;123;foo;123;

由于bar没有出现两次,它只会匹配:

foo;bar;123;foo;123;

我知道如何指定精确匹配两个结果,(foo|bar|123){2}但是为了使其在我的示例中工作,我需要使用反向引用。 我很难将这两个概念结合起来并制定一个可行的解决方案。


2
你使用哪种编程语言?在分号上进行拆分并使用类似于“if ... in ...”的东西可能会更容易。 - Jan
我不太清楚你的问题:你是想找出哪些单词出现了两次吗?如果一个单词出现超过两次,它算匹配吗? - glenn jackman
@Jan 我被绑定在一个旧的Oracle软件上,我只能将正则表达式作为选项粘贴到框中。 - Zalán Józsa
@glennjackman 我正在尝试找到仅出现两次的单词,我只有出现一次或两次的单词。我想匹配这些单词并替换它们,这将只留下不出现两次的单词。 - Zalán Józsa
2个回答

2
您可以使用

标签

(?<=^|;)([^\n;]+)(?=.*(?:(?<=^|;)\1(?=;|$)))


分解一下,这是

(?<=^|;)         # pos. loobehind, either start of string or ;
([^\n;]+)        # not ; nor newline 1+ times
(?=.*            # pos. lookahead
    (?:
        (?<=^|;) # same pattern as above
        \1       # group 1
        (?=;|$)  # end or ;
     )
)

\b       # word boundary
([^;]+)  # anything not ; 1+ times
\b       # another word boundary
(?=.*\1) # pos. lookahead, making sure the pattern is found again

请看regex101.com上的演示。

否则-如评论中所说-可以在程序上根据;进行分割,然后使用一些编程逻辑。

例如,可以在Python中找到演示(也可以针对其他语言进行调整):

from collections import Counter

string = """
foo;bar;123;foo;123;
foo;bar;foo;bar;
foo;foo;foo;bar;bar;
"""

twins = [element
        for line in string.split("\n")
        for element, times in Counter(line.split(";")).most_common()
        if times == 2]
print(twins)

3
支持“使用编程逻辑”的想法。这听起来并不像正则表达式应该处理的事情。 - user909694
1
尝试用 foo;bar;123;myfoo;123; 进行测试。 - Marco Luzzara
1
@MarcoLuzzara:现在看一下。 - Jan
1
@Jan 我更喜欢 https://regex101.com/r/ck7LDZ/6,甚至更喜欢 https://regex101.com/r/ck7LDZ/7。嗯嗯。 - ctwheels
1
@Jan 根据 Regular-Expressions.info 的说法,该正则表达式被 PCRE 7.2+、PHP 5.2.2+、Java 8+、JGsoft engine 2+ 支持。有些语言只匹配垂直制表符(而不是垂直空白字符,例如 C#JavaScript),而有些则匹配字面上的 v 字符。 - ctwheels
显示剩余3条评论

1
确保留出空间以容纳可能在“.*”匹配之间出现的文本,这应该匹配至少出现两次的任何值:
(foo|bar|123).*\1

foo;bar;foo;bar;怎么办? - ctwheels
抱歉,这不起作用,因为我不想匹配分号。 - Zalán Józsa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接