我正在做一个正则表达式课程的练习题:
你会如何写一个正则表达式来匹配第一个单词是Alice,Bob或Carol的句子;第二个单词是吃,宠物或扔;第三个单词是苹果,猫或棒球;句子以句号结尾?此正则表达式应不区分大小写。它必须与以下内容匹配:
- 爱丽丝吃苹果。
- 鲍勃养猫。
- 卡罗尔投掷棒球。
- 爱丽丝扔苹果。
- 鲍勃吃猫。
我的代码如下:
regex=re.compile(r'Alice|Bob|Carolseats|pets|throwssapples.|cats.|baseballs.',re.IGNORECASE)
mo=regex.search(str)
ma=mo.group()
当我传递str ='BOB EATS CATS.'
或'Alice throws Apples.'
时,mo.group()
分别只返回'Bob'
或'Alice'
,但我期待它返回整个句子。
当我通过str='Carol throws baseballs.'
时,mo.group()
返回'baseballs.'
,这是最后一场比赛。
我很困惑为什么:
对于我传递的前两个 str 示例,它返回第一个匹配项(
'Bob'
或'Alice'
(,而我传递的第 3 个 str 示例返回最后一个匹配项('baseball'
(?在所有 3 str 示例中,我不确定为什么
mo.group()
没有将整个句子作为匹配返回。 即我期望'Carol throws baseballs.'
作为mo.group()
的输出
你需要告诉你的正则表达式以某种方式对选项列表进行分组,否则它自然会认为它是一个巨大的列表,有些元素包含空格。最简单的方法是对每个单词使用捕获组:
regex=re.compile(r'(Alice|Bob|Carol)s+(eats|pets|throws)s+(apples|cats|baseballs).', re.IGNORECASE)
尾随期不应成为选项的一部分。如果出于某种原因不想使用捕获组(这不会真正影响匹配的进行方式(,则可以改用非捕获组。将(...)
替换为(?:...)
。
您的原始正则表达式被解释为以下一组选项:
Alice
Bob
Carolseats
pets
throwssapples.
cats.
baseballs.
空格不会神奇地分隔选项。希望你能明白为什么除了baseballs.
之外,Carol throws baseballs.
的所有元素都不存在于该列表中。不过,像Carol eats baseballs.
这样的东西会Carol eats
匹配。
你应该将所有单词分组
您的 RE 应如下所示:
regex = r'(?:Alice|Bob|Carol)s(?:eats|pets|throws)s(?:apples|cats|baseballs).'
请注意,我使用 (?:) 而不是 ((,因为分组仅用于逻辑目的
你也可以这样做:
(w{3,5}) (w*) ([^f]w+)