Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正则表达式中的Python正则表达式否定_Python_Regex - Fatal编程技术网

正则表达式中的Python正则表达式否定

正则表达式中的Python正则表达式否定,python,regex,Python,Regex,鉴于: 是否可以创建与最短版本的“ABC[\W\W]+?XYZ”匹配的正则表达式 本质上,我在寻找“ABC后跟以XYZ结尾的任何字符,但如果在两者之间遇到ABC,则不匹配”(但将ABC视为一个潜在的正则表达式本身,因为它并不总是一个固定长度……因此ABC或ABcC也可以匹配) 因此,更一般地说:REGEX1后跟任何字符,并以REGEX2结尾,如果REGEX1出现在两者之间,则不匹配 在本例中,我不需要前4行 (我相信这个解释可能需要…进一步解释哈哈) 编辑: 好吧,我觉得现在需要进一步解释了!谢

鉴于:

是否可以创建与最短版本的“ABC[\W\W]+?XYZ”匹配的正则表达式

本质上,我在寻找“ABC后跟以XYZ结尾的任何字符,但如果在两者之间遇到ABC,则不匹配”(但将ABC视为一个潜在的正则表达式本身,因为它并不总是一个固定长度……因此ABC或ABcC也可以匹配)

因此,更一般地说:REGEX1后跟任何字符,并以REGEX2结尾,如果REGEX1出现在两者之间,则不匹配

在本例中,我不需要前4行

(我相信这个解释可能需要…进一步解释哈哈)

编辑:

好吧,我觉得现在需要进一步解释了!谢谢你迄今为止的建议。在我开始研究如何将您提出的每个解决方案应用于我的问题时,我至少会给您更多的思考

方案1:反转字符串内容和正则表达式

这当然是一个非常有趣的黑客,根据我的解释解决了这个问题。在简化问题的过程中,我没有提到同样的事情可能会反过来发生,因为结尾的签名可能以后也会存在(并且已经证明在我的特定情况下)。这就引出了如下所示的问题:

ABC
content 1
123
content 2
ABC
content 3
XYZ
在本例中,我将检查类似“ABC通过XYZ”的内容,意思是捕获[ABC,内容1,XYZ]…但意外捕获[ABC,内容1,123,内容2,ABC,内容3,XYZ]。相反,这将捕获[ABC,内容3,XYZ,内容4,MNO,内容5,XYZ],而不是我们想要的[ABC,内容2,XYZ]。重点是尽可能地使其通用化,因为我还将搜索可能具有相同起始签名(本例中为regex“ABC”)和不同结束签名的内容

如果有一种方法可以构建正则表达式,使其封装这种限制,那么在我构建正则表达式以在这种类型的字符串中搜索时,只要引用它,而不是创建一个处理它的自定义搜索算法,就会变得容易得多

方案2:A+B+C++[^A]+[^B]+[^C]+XYZ,带IGNORECASE标志

在ABC是有限的情况下,这似乎很好。不过,可以把它本身看作是一个正则表达式。例如:

ABC
content 1
123
content 2
ABC
content 3
XYZ
content 4
MNO
content 5
XYZ
我正在尝试做的非常简单的版本。我想要“Hello.Later.”,因为起始regex Hello[!。]和结束后[!。]。稍后运行类似Hello[!。]的简单操作[!。]将获取整个字符串,但我想说的是,如果在找到的第一个起始regex实例和第一个结束regex实例之间存在start regex Hello[!。],请忽略它

这个提议下面的conva表明,我可能会受到常规语言的限制,类似于括号匹配问题(googleit,这很有趣)。这篇文章的目的是看看我是否真的需要创建一个底层算法来处理我遇到的问题。如果可能的话,我非常希望避免这种情况(在我上面给你的简单示例中,为……设计有限状态机非常容易……我希望随着它变得稍微复杂一些,这种情况仍然成立)

方案3:ABC(?(?!ABC)。*?带DOTALL标志的XYZ

我喜欢这个想法,如果它真的允许ABC成为正则表达式。当我明天到办公室时,我必须研究一下这个问题。乍一看,并没有什么事情看起来太不寻常,但我对python正则表达式是完全陌生的(而且不熟悉在代码中实际应用正则表达式,而不仅仅是理论作业)

Edit 因此,在阅读了您的进一步解释之后,我想说,我之前的建议以及MRAB的建议在某种程度上是相似的,在这里没有任何帮助。您的问题实际上是嵌套结构的问题

把你的“前缀”和“后缀”想象成符号。你可以很容易地用一个开括号和一个闭括号或其他什么来代替它们,你想要的是能够只匹配最小的(然后是最深的)一对

例如,如果前缀为“ABC”,后缀为“XYZ”:

Hello!GoodBye!Hello.Later.
您只想获取
ABCbarXYZ

如果前缀是
,后缀是
,则字符串为:

ABChello worldABCfooABCbarXYZ
理想情况下,它只匹配
(条形)

当然,您必须使用a(就像编程语言一样:,)和a,或者通过使用regex以及编程语言的迭代和存储机制来创建自己的

但是,仅使用正则表达式是不可能的。它们可能会对你的算法有所帮助,但它们并不是专门设计用来处理这个问题的。不是做那工作的好工具。。。你不能用螺丝刀给轮胎充气。因此,您必须使用一些外部机制(虽然并不复杂)来存储上下文,即您在嵌套堆栈中的位置。在每个上下文中使用正则表达式仍然是可能的

有限状态机是有限的,嵌套结构具有任意深度,这将要求您的自动机任意增长,因此它们不是

由于语法中的递归允许定义嵌套的语法结构,因此任何允许嵌套结构的语言(包括任何编程语言)都是上下文无关语言,而不是常规语言。例如,由平衡圆括号组成的字符串集[就像删除字母数字的LISP程序]是一种上下文无关语言

以前的提案(不再相关) 如果我这样做:

(hello world(foo(bar)
我明白了


这就是您想要的吗?

正则表达式解决方案将是带有
DOTALL
标志的
ABC(?(?!ABC)*?XYZ

解决此问题的另一种方法是:不尝试在一个正则表达式中执行此操作。可以按第一个正则表达式拆分字符串,然后在最后一部分使用第二个正则表达式

代码是最好的解释
>>> s = """ABC
content 1
123
content 2
ABC
content 3
XYZ"""
>>> r = re.compile(r'A+B+C+[^A]+[^B]+[^C]+XYZ', re.I)
>>> re.findall(r,s)
['ABC\ncontent 3\nXYZ']
s = """ABC
content 1
123
content 2
ABC
content 3
XYZ
content 4
XYZ"""

# capturing groups to preserve the matched section
prefix = re.compile('(ABC)')
suffix = re.compile('(XYZ)')

# prefix.split(s) == ['', 'ABC', [..], 'ABC', '\ncontent 3\nXYZ\ncontent 4\nXYZ']
#                          prefixmatch ^^^^^  ^^^^^^^^^^^^ rest ^^^^^^^^^^^^^^^^
prefixmatch, rest = prefix.split(s)[-2:]

# suffix.split(rest,1) == ['\ncontent 3\n', 'XYZ', '\ncontent 4\nXYZ']
#                          ^^ interior ^^   ^^^^^ suffixmatch
interior, suffixmatch = suffix.split(rest,1)[:2]

# join the parts up.
result = '%s%s%s' % (prefixmatch, interior, suffixmatch)

# result == 'ABC\ncontent 3\nXYZ'