我需要创建一个匹配可选组之前的所有内容的正则表达式,但是我需要将可选组优先于.
元字符。
只要该组不是可选的,一切都按照我的预期运作:
>>> re.match(r'(.+)(\d+)','asdasd2').groups()
('asdasd', '2')
但是,当将其标记为可选时,结果将不再符合我的需求:
>>> re.match(r'(.+)(\d+)?','asdasd2').groups()
('asdasd2', None)
使用?
上的非贪婪修饰符.
会让情况变得更糟:
>>> re.match(r'(.+?)(\d+)?','asdasd2').groups()
('a', None)
这是我在实际代码中使用的更复杂正则表达式的抽象,其中可选组本身非常复杂,因此使用[^somecharacter]
而不是.
不是一种选择。有没有解决这个问题的方法?
答案 0 :(得分:2)
我认为这可能是您正在寻找的,假设您总是希望从搜索中返回两个组:
>>> re.match(r'(.+(?=\d+)|.+)(\d+)?', 'asdasd2').groups()
('asdasd', '2')
>>> re.match(r'(.+(?=\d+)|.+)(\d+)?', 'asdasd').groups()
('asdasd', None)
第一组(.+(?=\d+)|.+)
查找一组字符后跟一个数字(但不包括数字)或只查找一组字符(隐含地后面没有数字,因为那个案例会被抓住由(.+(?=\d+)
)。第二组(\d+)?
查找一组数字的0或1次出现。
答案 1 :(得分:1)
使用|
运算符来表示包含和不包含可选组的表达式。
(?:(.+)(\d+)|(.+))
>>> re.match(r'(?:(.+)(\d+)|(.+))','asdasd2').groups()
('asdasd', '2', None)
>>> re.match(r'(?:(.+)(\d+)|(.+))','asdasd').groups()
(None, None, 'asdasd')
>>> re.match(r'(?:(.+)(\d+)|(.+))','asdasd23abc3').groups()
('asdasd23abc', '3', None)