如何为两个正则表达式的“交集”编写正则表达式,可用于匹配字符串中的任何位置

时间:2014-06-11 03:07:49

标签: regex

考虑到两个正则表达式,我们是否可以编写一个正则表达式来表示它们在以下两种差异感中的“交叉点”,以便匹配字符串中的任何位置?

  1. 鉴于两个正则表达式expr1expr2,我们可以写一个正则表达式 它表示两个给定正则表达式的交集,在集合交集的意义上,它 正则表达式可用于匹配字符串中的任何位置吗?

    例如,expr1(123|12345|abc|abcde)expr2(345|12345|abc|de)。我想找一个代表的正则表达式 (12345|abc)
    因此,在将正则表达式应用于blah12345blahabcdeblah时,匹配 在应用正则表达式时,12345abcblah123blahabcblahabc (?=^expr1$)(?=^expr2$).*,匹配为^

    $有锚点expr1expr2,可以阻止它在字符串中间找到匹配项。

  2. 鉴于两个正则表达式expr1(123|abcde),我们如何编写正则表达式 它代表了两个给定正则表达式的“交集” 感觉它由那些字符串组成,每个字符串

    • 出现在两个正则表达式中的至少一个中,
    • 在两个正则表达式的其余部分中有一个前缀,

    并且正则表达式可用于匹配字符串中的任何位置?

    例如,expr2(12345|abc)(12345|abcde)blah12345blahabcdeblah。 我想找一个代表12345的正则表达式 因此,在将正则表达式应用于abcde时,匹配 是blah123blahabcblah123,同时应用正则表达式 abc,没有匹配项(12345123不匹配)。

  3. 在应用正则表达式匹配字符串中间时,第2部分中“交集”的定义比第1部分中的定义更自然:

    在上面的示例中,只要12345匹配,expr1也会出现,expr2似乎同时位于12312345,应该在他们的“十字路口”。如果blah123blahabcblah匹配,则123不一定匹配,例如,在abcde中,因此{“1}}不会在”交叉点“中考虑。 abc的类似解释是{{1}}并不在“交集”中。

    谢谢!

2 个答案:

答案 0 :(得分:2)

第1部分

我还没有找到解决方案,会再看一下。

回答第2部分

这是一个适用于正则表达式引擎的解决方案,允许反向引用外观,例如.NET和Matthew Barnett对Python的优秀regex模块。

对于你的例子:

(?x)
(?=(12345|abc))(?=(123|abcde)) # AND the expressions
(?: # take the longest match
\1(?<=\2.*) #abcde, \1 is abc
|
\2(?<=\1.*) #12345, \2 is 123
) 

一般来说:

(?x)
(?=(expr1))(?=(expr2)) # AND the expressions
(?: # take the longest match
\1(?<=\2.*) 
|
\2(?<=\1.*) 
) 

我认为这很有效......但也许有一个我没想过的边缘情况。

以下是一些经过测试的Python代码。

import regex
pattern = r'''(?x)
(?=(12345|abc))(?=(123|abcde)) # AND the expressions
(?: # take the longest match
\1(?<=\2.*) #abcde, \1 is abc
|
\2(?<=\1.*) #12345, \2 is 123
)
'''
myregex = regex.compile(pattern)

print ("--- blah12345blahabcdeblah ---")
for match in myregex.finditer("blah12345blahabcdeblah"):
    print("Overall match: ", match.group(0))

print ("--- blah123blahabcblah ---")
for match in myregex.finditer("blah123blahabcblah"):
    print("Overall match: ", match.group(0))

print ("--- blah12345blahabcdeblah12345 ---")
for match in myregex.finditer("blah12345blahabcdeblah12378"):
    print("Overall match: ", match.group(0))

答案 1 :(得分:1)

这些应该这样做:

  1. /(?=expr1(.*)$)expr2(?=\1$)/
  2. /(?=expr1)(?=expr2)/