我对正则表达式的结果不如预期。

3
我正在寻找text6中包含字母z或者字符序列pt,或以ize结尾的单词。
我写了下面的代码,但是它包含了很多不符合上述条件的单词,比如appease、dance、offensive、executive等。为什么会发生这种情况?
L2=[w for w in text6 if re.search(r".*[z]|.*[p][t]|[ize]$",w)

另一个问题是在之前的练习基础上构建的:我需要添加一个新的替代条件,即单词以1开头,并且只有一个大写字母。
我写了
L2=[w for w in text6 if re.search(r"[A-Z]{1}|.*[z]|.*[p][t]|[ize]$",w)

它还包括大写字母(即所有字符都是大写字母)

我该如何解决这些问题?


1
在您的第一个情况中,ize$ 是必要的吗?任何包含此模式的单词也会被仅使用 z 捕获吗? - Psidom
3个回答

2
你正在遍历字符而不是单词,这种情况下你需要分割你的文本。
此外,你可以不使用正则表达式来完成所有这些工作:
from string import ascii_uppercase

def check_word(word):
    return 'z' in word or 'pt' in word or word.endswith('ize') or word.startswith(tuple(ascii_uppercase))

[w for w in text6.split() if check_word(w)]

演示:

>>> text6 = "here are some example: appease dance offensive xxxize executive and other extra words optimum Python"
>>> [w for w in text6.split() if check_word(w)]
['xxxize', 'optimum', 'Python']

对于最后一个条件(单词以1个大写字母开头),如果你不想在单词中除了第一个字母外有其他大写字母,你可以在 check_word 函数中添加 (word[1:].islower()):

def check_word(word):
    return 'z' in word or 'pt' in word or word.endswith('ize') or (word.startswith(tuple(ascii_uppercase)) and word[1:].islower())
注意:如果你想用多个分隔符或基于其他条件分隔单词,可以使用re.findall()来查找单词。

例如,以下正则表达式将查找包含单词字符的单词:

re.findall(r'\b\w+\b', my_str)

2
我建议在这里采用非正则表达式的方法,因为正则表达式似乎比这种情况要求更复杂。
首先,你可以去掉“以ize结尾”的限制,因为这个条件适用于任何带有z的单词。
text6 = [
    'appease', 'dance', 'offensive', 'executive',
    'inept', 'zoo', 'Inept', 'Zoo', 'INept', 'ZOo']

仅匹配小写的单词ptz
[w for w in text6 if 'pt' in w or 'z' in w]  # ['inept', 'zoo', 'Inept', 'INept']

为了匹配上述情况以及仅大写字母单词:

[w for w in text6 if w.istitle() and ('pt' in w or 'z' in w)]  # ['Inept']

当然,编写一个抽象出这个逻辑的函数可能会更好:

def meets_criteria(word):
    return word.istitle() and ('pt' in word or 'z' in word)

[w for w in text6 if meets_criteria(w)]

如果你想匹配以ZPt开头的单词,可以检查w.lower()是否在其中。

1
你所寻找的是:
[w for w in text6 if re.search(r"z|pt|ize$", w)]

这将捕获所有必需的单词。请注意,最后一部分并非必需,因为与ize$匹配的任何单词也将与z匹配。因此,本质上,表达式简化为:
[w for w in text6 if re.search(r"z|pt", w)]

第二种情况可以通过使用表达式 ^[A-Z]{1}[^A-Z]来解决。也就是说,

  • 以一个大写字母开头
  • 后面没有大写字母

以下是使用示例:

[w for w in text6 if re.search(r"^[A-Z]{1}[^A-Z]|z|pt|ize$", w)]

或者,简单地说,
[w for w in text6 if re.search(r"^[A-Z]{1}[^A-Z]|z|pt", w)]

假设text6是一个单词列表。如果不是,请像@Kasramvd指出的那样在text6.split()上运行循环。 - agamagarwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接