Python 如何使用正则表达式搜索句子内部-不区分大小写

Python 如何使用正则表达式搜索句子内部-不区分大小写,python,regex,list,search,Python,Regex,List,Search,我是Python正则表达式的新手: 我有一个列表,我想搜索它是否包含员工姓名 员工姓名可以是: 它可以在开始时后跟空格 其次是 或者后面跟着空格 或者可以在末尾和前面的空格处 不区分大小写 列表语句的输出为: ["Steve®", "Rob spring", "Car Daniel", "Done daniel"] 如果您只是查找包含空格的字符串,如您的示例所示,它应该是这样的: [i for i in ListSentence if i.endswith('®') or (' '

我是Python正则表达式的新手:
我有一个列表,我想搜索它是否包含员工姓名

员工姓名可以是:

  • 它可以在开始时后跟空格
  • 其次是
  • 或者后面跟着空格
  • 或者可以在末尾和前面的空格处
  • 不区分大小写


列表语句的输出为:

["Steve®", "Rob spring", "Car Daniel", "Done daniel"]

如果您只是查找包含空格的字符串,如您的示例所示,它应该是这样的:

[i for i in ListSentence if i.endswith('®') or (' ' in i)]

首先,获取所有员工姓名,并使用
|
字符将其连接起来,然后将字符串换行,使其看起来像:

(?:^ |\s)((?:史蒂夫|罗布|丹尼尔)(?:丹尼尔)?)(?=\s |$)

通过首先将所有名称连接在一起,可以避免使用一组嵌套的for next循环的性能开销

我对python的了解还不足以提供python示例,但是在powershell中,我会这样编写它

[array]$names = @("Steve", "Rob", "daniel")
[array]$ListSentence = @("Steve®", "steveHotel", "Rob spring", "Car Daniel", "CarDaniel","Done daniel")

# build the regex, and insert the names as a "|" delimited string
$Regex = "(?:^|\s)((?:" + $($names -join "|") + ")(?:®)?)(?=\s|$)" 

# use case insensitive match to find any matching array values
$ListSentence -imatch $Regex
屈服

Steve®
Rob spring
Car Daniel
Done daniel

为什么要使用正则表达式?我通常建议在Python中避免使用它们——您可以改用字符串方法

例如:

def string_has_employee_name_in_it(test_string):
    test_string = test_string.lower() # case insensitive
    for name in ListEmployee:
        name = name.lower()
        if name == test_string:
            return True
        elif name + '®' == test_string:
            return True
        elif test_string.endswith(' ' + name):
            return True
        elif test_string.startswith(name + ' '):
            return True
        elif (' ' + name + ' ') in test_string:
            return True
    return False   

final_list = []
for string in ListSentence:
    if string_has_employee_name_in_it(string):
        final_list.append(string)

最终列表是您想要的列表。这比正则表达式长,但也更容易解析和维护。您可以通过各种方式将它缩短很多(例如,在函数中组合测试,并使用列表理解而不是循环),但是当您开始使用Python时,最好弄清楚发生了什么。

我认为您不需要检查所有这些场景。我想你所需要做的就是检查是否有断字

您可以使用
|
加入ListEmployee列表以生成一个或正则表达式(也可以将其小写以表示大小写不敏感),并用
\b
包围以表示分词,这样应该可以:

regex = '|'.join(ListEmployee).lower()
import re
[l for l in ListSentence if re.search(r'\b(%s)\b' % regex, l.lower())]
应输出:

['Steve\xb6\xa9', 'Rob spring', 'Car Daniel', 'Done daniel']
一种可能的解决办法:

import re

ListSentence = ["Steve®", "steveHotel", "Rob spring", "Car Daniel", "CarDaniel","Done daniel"]
ListEmployee = ["Steve", "Rob", "daniel"]


def findEmployees(employees, sentence):
    retval = []
    for employee in employees:
        expr = re.compile(r'(^%(employee)s(®)?(\s|$))|((^|\s)%(employee)s(®)?(\s|$))|((^|\s)%(employee)s(®)?$)' 
            % {'employee': employee}, 
          re.IGNORECASE)
        for part in sentence:
            if expr.search(part):
                retval.append(part)
    return retval



findEmployees(ListEmployee, ListSentence)

>> Returns ['Steve\xc3\x82\xc2\xae', 'Rob spring', 'Car Daniel', 'Done daniel']


真的
吗?
?这是unicode的问题吗?你能说得更清楚些吗
Rob spring
后面没有空格,也不是“结尾和前面的空格”。是的。这是一个商业标志,我的错,我没有把它添加到条件列表中,我编辑了我的问题,它可以在开头加空格。看起来很棒!你能给我一个如何使用上述代码的例子吗?非常感谢!!很好的图表,你用什么做的?非常感谢你的精彩解释,图表帮助我理解了你的方法!!再一次打败你!!我正在使用debuggex.com。尽管它不支持lookbehind或原子组,但它仍然便于理解表达式流。还有regexper.com。他们也做得很好,但在你打字时不是实时的。我有个问题。使正则表达式不捕获(例如
(?:Steve | Rob | Daniel)
而不仅仅是
(Steve | Rob | Daniel)
会提高性能吗?非常感谢您的快速响应!!它需要与员工列表一起检查,因此只搜索列出的员工。您可能是正确的,因为OP不需要使用正则表达式。我觉得也不需要这么复杂。我想你们可以去掉那个些unicode字符,然后检查一下列表中的名字,非常好!删除unicode字符并进行直接检查!!我爱死它了!!今天晚上我学到了很多!谢谢大家!!!!'若“列表中的名字”给出了“卡丹尼尔”的假阳性,OP不想要。删除Unicode也会引发一些误报——例如,如果它在单词的中间。实际上,这可能不是一个问题,在这种情况下,剥离unicode是可以的。我认为@Ben Lerner也有道理。你可能根本不需要正则表达式。我将在我的解决方案中添加一种不使用正则表达式的方法。请注意,此处的
\b
符号将允许像
dog&daniel#moretext
这样的字符串,这将使criteria@Denomales对的然而,我认为这将是一个更实际的解决方案。我简直无法想象为什么有人会雇佣一个叫
狗%daniel#moretext
的人。谢谢你指出这一点,我没有看到,有趣的不是员工的名字,而是输入这些名字的人没有正确输入,或者当数据在btw数据库中移动时,有时会很有趣。你的右边是一个延伸,但是想象一下某人的姓氏带有连字符
Ray Steven
,这可以与
\bRay\b
\b甚至\b
re.compile()
函数的伟大调用相匹配!!谢谢你,奥伦科!!请注意,@Denomales关于
\b
的评论也适用于\W。我将在一分钟内用更健壮的正则表达式更新我的正则表达式。非常感谢Orlenko!!更新。单词边界在这个单词中应该正常工作。
import re

ListSentence = ["Steve®", "steveHotel", "Rob spring", "Car Daniel", "CarDaniel","Done daniel"]
ListEmployee = ["Steve", "Rob", "daniel"]


def findEmployees(employees, sentence):
    retval = []
    for employee in employees:
        expr = re.compile(r'(^%(employee)s(®)?(\s|$))|((^|\s)%(employee)s(®)?(\s|$))|((^|\s)%(employee)s(®)?$)' 
            % {'employee': employee}, 
          re.IGNORECASE)
        for part in sentence:
            if expr.search(part):
                retval.append(part)
    return retval



findEmployees(ListEmployee, ListSentence)

>> Returns ['Steve\xc3\x82\xc2\xae', 'Rob spring', 'Car Daniel', 'Done daniel']