如何使用正则表达式在句子内搜索 - 不区分大小写
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)]
【讨论】:
非常感谢您的快速回复!!它要与员工列表一起检查,因此只搜索列出的员工。以上是关于如何使用正则表达式在句子内搜索 - 不区分大小写的主要内容,如果未能解决你的问题,请参考以下文章