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

Posted

技术标签:

【中文标题】如何使用正则表达式在句子内搜索 - 不区分大小写【英文标题】:How can I use regex to search inside sentence -not a case sensitive 【发布时间】:2013-06-12 23:26:26 【问题描述】:

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

员工姓名可以是:

可以在开头跟空格。 后跟 ® OR 后跟空格 或可以在末尾和之前的空格 不区分大小写
ListSentence = ["Steve®", "steveHotel", "Rob spring", "Car Daniel", "CarDaniel","Done daniel"]
ListEmployee = ["Steve", "Rob", "daniel"]

ListSentence 的输出是:

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

【问题讨论】:

真的®?这是 unicode 故障吗? 你能说得更清楚一点吗? Rob spring 后面没有空格,也不是“在末尾和前面的空格”。 是的。这是一个商业标志, 我的不好我没有将它添加到条件列表中,我编辑了我的问题,它可以在开头后跟空格。 【参考方案1】:

一个可能的解决方案:

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']

【讨论】:

强烈要求re.compile()函数!!谢谢奥连科!! 请注意@Denomales 对\b 的评论也适用于\W。我将在一分钟内用更强大的正则表达式更新我的正则表达式。 非常感谢奥连科!! 已更新。这个词边界应该在这个中正常工作。【参考方案2】:

首先获取所有员工姓名,并使用| 字符将它们连接起来,然后将字符串包装成如下所示:

(?:^|\s)((?:Steve|Rob|Daniel)(?:®)?)(?=\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

【讨论】:

看起来很棒!你能给我一个如何使用你上面的代码的例子吗?非常感谢!! 不错的图,你用什么做的? 非常感谢@Denomales 的精彩解释,图表帮助我理解了你的方法!!再次坦克你! 我正在使用 debuggex.com。尽管它不支持lookbehinds 或原子组,但它对于理解表达式流仍然很方便。还有 regexper.com。它们也做得很好,但在您输入时并不是实时的。 我有一个问题。是否使正则表达式不被捕获,例如(?:Steve|Rob|Daniel) 而不是 (Steve|Rob|Daniel) 提高性能?【参考方案3】:

我认为您不需要检查所有这些情况。我认为您需要做的就是检查断字。

您可以使用 | 加入 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']

【讨论】:

好。我认为@Ben Lerner 也有道理。您可能根本不需要正则表达式。我将在我的解决方案中添加一种无需正则表达式的方法。 请注意这里的\b 符号将允许dog&daniel#moretext 之类的字符串不符合条件 @Denomales 正确。但是,我认为这将是一个更实用的解决方案。我只是无法想象为什么有人会雇用一个叫dog%daniel#moretext的人。 感谢@Denomales 指出这一点,我没看到,不是员工姓名好笑,而是输入这些姓名的人没有正确输入或数据顺便说一句,在数据库中移动它有时会很有趣。 你的权利有点牵强,但是想象一下带有连字符的姓氏Ray-Steven,这可以与\bRay\b\bSteven\b匹配【参考方案4】:

为什么要使用正则表达式?我通常建议在 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)

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

【讨论】:

您可能是正确的,因为 OP 不需要使用正则表达式。我也不认为它需要这么复杂。我想你可以去掉那些 unicode 字符并检查if name in list @bozdoz,非常好!删除 unicode 字符并直接检查!我喜欢它!!今天晚上我学到了很多东西!谢谢大家!!!! 'if name in list' 给出了 'CarDaniel' 的误报,这是 OP 不想要的。删除 unicode 也会引发一些误报 - 例如如果它在单词的中间。在实践中这可能不是问题,在这种情况下剥离 unicode 是可以的。【参考方案5】:

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

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

【讨论】:

非常感谢您的快速回复!!它要与员工列表一起检查,因此只搜索列出的员工。

以上是关于如何使用正则表达式在句子内搜索 - 不区分大小写的主要内容,如果未能解决你的问题,请参考以下文章

Mongo中不区分大小写的搜索

shell:正则表达式和文本处理

第九章 使用正则表达式进行搜索

JavaScript RegExp(正则表达式) 对象

MySQL中的Like和正则表达

使用正则表达式进行搜索