正则表达式:确保b不在a和c之间

时间:2016-05-15 15:53:40

标签: regex python-2.7

这是我尝试用正则表达式做的事情,我无法弄清楚如何做。我有一个大文件,以及在整个文件中多次出现的字符串abc123xyz

我想要一个正则表达式来匹配以abc开头的大文件的子字符串,在中间某处包含123,以xyz结尾,并且除了开头和结尾之外,子字符串中没有abcxyz的其他实例。

这是否可以使用正则表达式?

4 个答案:

答案 0 :(得分:29)

您需要 tempered greedy token

abc(?:(?!abc|xyz|123).)*123(?:(?!abc|xyz).)*xyz

请参阅regex demo

要确保它跨行匹配,请在编译正则表达式时使用re.DOTALL标志。

请注意,为了在如此繁重的模式下获得更好的性能,您应该考虑展开它。它可以用否定的字符类和负向前瞻来完成。

模式详情

  • abc - 匹配abc
  • (?:(?!abc|xyz|123).)* - 匹配任何不是abcxyz123字符序列起点的字符
  • 123 - 文字字符串123
  • (?:(?!abc|xyz).)* - 任何不是abcxyz字符序列起点的字符
  • xyz - 尾随子字符串xyz

请参阅下图(如果使用re.S.将表示AnyChar):

enter image description here

请参阅Python demo

import re
p = re.compile(r'abc(?:(?!abc|xyz|123).)*123(?:(?!abc|xyz).)*xyz', re.DOTALL)
s = "abc 123 xyz\nabc abc 123 xyz\nabc text 123 xyz\nabc text xyz xyz"
print(p.findall(s))
// => ['abc 123 xyz', 'abc 123 xyz', 'abc text 123 xyz']

答案 1 :(得分:3)

使用PCRE的解决方案是:

这使用m标志。如果您只想从一行的开头和结尾检查,请分别在开头和结尾添加^$

abc(?!.*(abc|xyz).*123).*123(?!.*(abc|xyz).*xyz).*xyz

Regular expression visualization

Debuggex Demo

答案 2 :(得分:2)

comment hvd非常合适,这只是一个例子。例如,在SQL中,我认为这样做会更清楚:

where val like 'abc%123%xyz' and
      val not like 'abc%abc%' and
      val not like '%xyz%xyz'

我认为在其他环境中很容易做到相似的事情。

答案 3 :(得分:1)

您可以使用环视。

/^abc(?!.*abc).*123.*(?<!xyz.*)xyz$/g

(我还没有测试过。)