簡體   English   中英

Python正則表達式匹配前一組中匹配的任何內容(多個選項中的1個)

[英]Python regex matching whatever matched in previous group (1 out of multiple options)

假設我有正則表達式(?:AA|BB)(.*)(?:AA|BB) ,它捕獲分隔符AABB之間的所有內容

我遇到的問題是這也會匹配AA...BB

我怎樣才能使正則表達式只匹配AA...AABB...BB

如果您需要匹配開頭和結尾的字符串與相同的前導和尾隨分隔符 ,您只需要捕獲前導分隔符並在模式本身內部使用反向引用

(AA|BB)(.*)\1
^     ^    ^^

請參閱正則表達式演示

在Python中,如果您只想獲得所需的組,則必須使用re.finditer ,而不是將返回元組列表的re.findall (因此將包含AABB )。 要匹配從AA到第一個下一個AA的子串,請使用惰性量詞*? (AA|BB)(.*?)\\1

一個簡短的Python演示

import re
p = re.compile(r'(AA|BB)(.*)\1')
test_str = "AA text AA"
print([x.group(2).strip() for x in p.finditer(test_str)])
# => ['text']

如果需要匹配前導和尾隨分隔符不匹配的字符串,則必須使用替換

AA(.*)AA|BB(.*)BB

或者 - 一個懶惰的量詞版本,以匹配最接近的AABB s:

AA(.*?)ZZ|BB(.*?)YY

請注意,這將在結果中輸出空元素,因為只匹配一個組。 在大多數Python構建中,如果計划在re.sub使用它,則應謹慎使用此模式(直到Python 3.5,未匹配的組未使用空字符串(= None)初始化)並且可能拋出異常。

這是一個帶有re.finditer提取示例代碼

import re
p = re.compile(r'(AA)(.*?)(ZZ)|(BB)(.*?)(YY)')
test_str = "AA Text 1 here ZZ and BB Text2 there YY"
print("Contents:") 
print([x.group(2).strip() for x in p.finditer(test_str) if x.group(2)])
print([x.group(5).strip() for x in p.finditer(test_str) if x.group(5)])
print("Delimiters:")
print([(x.group(1), x.group(3)) for x in p.finditer(test_str) if x.group(1) and x.group(3)])
print([(x.group(4), x.group(6)) for x in p.finditer(test_str) if x.group(4) and x.group(6)])

結果:

Contents:
['Text 1 here']
['Text2 there']
Delimiters:
[('AA', 'ZZ')]
[('BB', 'YY')]

在現實生活中,使用非常長而復雜的文本,可以展開這些正則表達式以使匹配線性和高效,但這是一個不同的故事。

最后但並非最不重要的是, 如果您需要將最短的子字符串從一個分隔符匹配到另一個不包含這些分隔符的子字符串 ,請使用一個淬火的貪婪令牌

AA((?:(?!AA|ZZ).)*)ZZ|BB((?:(?!BB|YY).)*)YY
   ^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^^ 

請參閱正則表達式演示以查看與AA(.*?)ZZ|BB(.*?)YY的區別。

嘗試這個

AA(.*)AA|BB(.*)BB

看看這個例子

問題很混亂。 根據我的理解,你希望它匹配AA..AA或BB..BB,但不匹配它當前匹配的AA..BB。 我對正則表達式很糟糕,但我認為這應該有效:
編輯:對不起,SE格式搞砸了。

(?:(AA(.*)AA)|(BB(.*)BB))


>>> data = ['AAsometextAA', 'BBothertextBB', 'NotMatched', 'AAalsonotmatchedBB']
>>> matches = filter(lambda x: x is not None, [re.match("(?:(AA(.*)AA)|(BB(.*)BB))", datum) for datum in data])
>>> matches
[<_sre.SRE_Match object at 0x007DC078>, <_sre.SRE_Match object at 0x007DC288>]
>>> for match in matches:
...     print(match.group(0))
...
AAsometextAA
BBothertextBB
>>>

這應該適合你。

(AA(.*)AA)|(BB(.*)BB)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM