正则表达式匹配某模式或预定义字符串

0 投票
2 回答
1005 浏览
提问于 2025-04-16 08:41

我有两个字符串:

a = 'B E R L I N IS A CITY'
b = 'PARIS IS A CITY, TOO'

我想要匹配第一个单词,条件是它要么有一个空格,要么是一个预定义的单词。

我想到的正则表达式(用Python写的)是:

regex = re.compile('^(?P<city>([a-z] )*|(paris )).*$', re.IGNORECASE)
print regex.match(a).group('city'), regex.match(b).group('city')
>>>> ('B E R L I N ', '')

巴黎没有被匹配到。但是当我把正则表达式的顺序调换时,

regex = re.compile('^(?P<city>(paris )|([a-z] )*).*$', re.IGNORECASE)
print regex.match(a).group('city'), regex.match(b).group('city')
>>>> ('B E R L I N ', 'PARIS ')

巴黎就被匹配到了。我漏掉了什么呢?

2 个回答

2

使用 span() 通常能帮助我们发现问题,

import re

regex = re.compile('^(?:((?:[a-z] )*)|(paris )).*$', re.IGNORECASE)

a = 'B E R L I N IS A CITY'
b = 'PARIS IS A CITY, TOO'
for x in (a,b):
    print x
    print 'span(1)==',regex.match(x).span(1),'  span(2)==',regex.match(x).span(2)
    print

结果是:

B E R L I N IS A CITY
span(1)== (0, 12)   span(2)== (-1, -1)

PARIS IS A CITY, TOO
span(1)== (0, 0)   span(2)== (-1, -1)
5

这个“问题”在于,^([a-z] )* 这个表达式在字符串 PARIS … 的开头匹配成功了,因为 [a-z] 可以重复零次。所以正则表达式的解析器不需要去检查字面上的 paris

+ 替代 *,这样就能按预期工作了:

^(?P<city>([a-z] )+|(paris )).*$

撰写回答