【问题标题】:Matching terms that contain special characters with re.findall()?使用 re.findall() 匹配包含特殊字符的术语?
【发布时间】:2015-05-14 16:42:09
【问题描述】:

使用re.findall(),我试图从字符串中的术语列表中查找每个术语的所有出现。

如果特定术语包含特殊字符(即a '+'),将找不到匹配项,或者可能会生成错误消息。使用re.escape(),可以避免错误消息,但在字符串中找不到带有特殊字符的术语。

import re         
my_list = ['java', 'c++', 'c#', '.net']
my_string = ' python javascript c++ c++ c# .net java .net'
matches = []

for term in my_list:
    if any(x in term for x in ['+', '#', '.']):
        term = re.escape(term)

    print "\nlooking for term '%s'" % term 
    match = re.findall("\\b" + term + "\\b", my_string, flags = re.IGNORECASE)
    matches.append(match)

上面的代码只会在字符串中找到'java'。 有关如何在字符串中查找具有特殊字符的术语的任何建议?

警告:我无法手动更改“my_list”,因为我事先不知道它将包含哪些术语。

更新 - 问题似乎与正则表达式(“\b”)中的单词边界说明符有关,它沿着包含非字母数字字符的字符分解字符串字符串。然而,目前还不清楚如何以一种简洁明了的方式解决这个问题。

编辑 - 这个问题不是 this 的重复 - 它已经包含了该帖子中最适用的解决方案。

【问题讨论】:

  • 通过添加反斜杠\+来转义它们
  • + 表示正则表达式中非常具体的东西......你可以尝试转义它C\+\+
  • 'c++' 中,单词边界出现在c+ 之间。在您的正则表达式中,您将边界放在最后一个 + 之后。
  • 您的问题不是转义字符,而是您的 \\b 您在该术语周围有问题。如果你把它们拿出来,你会得到匹配。我知道你只想允许完整的单词匹配,但转义词不是你的问题。进一步研究。
  • Steven Rumbalski 是正确的,问题是非单词 (\w) 字符旁边的 \\b 因为它们将构成单词边界,因此你不能真正做到这一点。你最好关闭标记字符串并在每个标记上使用您的模式,而其中没有 \\b。

标签: python regex


【解决方案1】:
import re
my_list = ['java', 'c++', 'c#', '.net']
my_string = ' python javascript c++ c++ c# .net java .net'
matches = []

for term in my_list:
    if any(x in term for x in ['+', '#', '.']):
        term = re.escape(term)

    print "\nlooking for term '%s'" % term
    match = re.findall(r"(?:^|(?<=\s))"+term+r"(?=\s|$)", my_string, flags = re.IGNORECASE)
    matches.append(match)

试试这个。问题是\b是单词边界。在C+++之后没有单词边界。所以它不会匹配。其他人也是如此。

【讨论】:

  • 这似乎解决了问题。谢谢!
【解决方案2】:

查看python的regex syntax

  • + - 是正则表达式中使用的特殊字符,必须通过\ 转义

'+' - 使生成的 RE 匹配 1 次或多次重复的 前RE。 ab+ 将匹配 ‘a’ 后跟任何非零数量的 'b's;它不会只匹配“a”。

  • 在这种情况下,用于匹配您的正则表达式字符串中出现的不止一次。

例如,这将提取字符串中的整个数字序列:

re.findall('[0-9]+', 'This 0123435124 is a string with numbers')

这将找出0123435124,而这只会为您检索0

re.findall('[0-9]', 'This 0123435124 is a string with numbers')

最快的解决方法

my_list = ['java', 'c\+\+', 'c#', '\.net']
for key in my_list:
    match = re.findall("\\b" + key + "\\b", my_string, flags = re.IGNORECASE)

另一种解决方案是“动态”翻译对象或转义它们。

【讨论】:

  • 道歉 - 我没有在帖子中指定我事先不知道“my_list”(要在字符串中找到的术语列表)是什么,所以我不能手动添加反斜杠到特殊字符。
猜你喜欢
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多