Python 匹配字典问题中的各种关键字

Python matching various keyword from dictionary issues

我有一个复杂的文本,我在其中对存储在字典中的不同关键字进行分类:

    text = 'data-ls-static="1">Making Bio Implants, Drug Delivery and 3D Printing in Medicine,MEDICINE</h3>'

    sector = {"med tech": ['Drug Delivery' '3D printing', 'medicine', 'medical technology', 'bio cell']}

这可以成功找到我的关键字并对其进行分类,但有一些限制:

    pattern = r'[a-zA-Z0-9]+'

    [cat for cat in sector if any(x in re.findall(pattern,text) for x in sector[cat])]

我无法解决的限制是:

  1. 例如,由 space 分隔的“药物输送”等关键字无法识别,因此不会被分类。

  2. 我无法使模式不区分大小写,因为无法识别像 MEDICINE 这样的词。我尝试将 (?i) 添加到模式中,但它不起作用。

  3. 分类的关键字进入pandas df,但它们被打印到[]。我试图再次循环脚本以将它们取出,但它们仍然存在。

数据到 pandas df:

    ind_list = []
    for site in url_list:
        ind = [cat for cat in indication if any(x in re.findall(pattern,soup_string) for x in indication[cat])]
        ind_list.append(ind)

    websites['Indication'] = ind_list

当前输出:

Website                                  Sector                              Sub-sector                                 Therapeutical Area Focus URL status
0     url3.com                              [med tech]                                      []                                                 []          []         []
1     www.url1.com                    [med tech, services]                                      []                       [oncology, gastroenterology]          []         []
2     www.url2.com                    [med tech, services]                                      []                                        [orthopedy]          []         []

在输出中我得到了我想避免的 []。

你能帮我解决这些问题吗?

谢谢!

findall 在这里非常浪费,因为您要为每个关键字重复分解字符串。

如果要测试关键字是否在字符串中:

[cat for cat in sector if any(re.search(word, text, re.I) for word in sector[cat])]
# Output: med tech

你能试试正则表达式以外的其他方法吗,
当你有两个相似的匹配词时,我会建议 difflib

这里给大家提示一下容易发现的问题:

  1. 为什么不能匹配由 space 分隔的关键字,如“Drug Delivery”? 这是因为正则表达式模式 r'[a-zA-Z0-9]+' 与 space 不匹配。如果您还想匹配 space,可以将其更改为 r'[a-zA-Z0-9 ]+'(在 9 之后添加 space)。但是,如果要支持其他类型的白色 spaces(例如 \t、\n),则需要进一步更改此正则表达式模式。

  2. 为什么不支持不区分大小写的匹配?你的代码片段any(x in re.findall(pattern,text) for x in sector[cat])要求x具有相同的upper/lower 情况下,两者都是 re.findallsector[cat] 的结果。甚至无法通过在 re.findall() 调用中设置 flags=re.I 来绕过此限制。建议您在检查之前将它们全部转换为相同的大小写。也就是说,例如在匹配之前将它们全部更改为小写: any(x in re.findall(pattern,text.lower()) for x.lower() in sector[cat]) 这里我们将 .lower() 添加到 textx.lower().

通过以上 2 处更改,您应该可以捕获一些分类关键字。

实际上,对于这种特殊情况,您可能根本不需要使用正则表达式和 re.findall。您可以检查例如sector[cat][i].lower()) in text.lower()。即,将列表理解更改为:

[cat for cat in sector if any(x in text.lower() for x in [y.lower() for y in sector[cat]])]

编辑

测试 运行 使用 2 个单词的短语:

text = 'drug delivery'
sector = {"med tech": ['Drug Delivery', '3D printing', 'medicine', 'medical technology', 'bio cell']}
[cat for cat in sector if any(x in text.lower() for x in [y.lower() for y in sector[cat]])]

Output:       # Successfully got the categorizing keyword even with dictionary values of different upper/lower cases
['med tech']

text = 'Drug Store fast delivery'
[cat for cat in sector if any(x in text.lower() for x in [y.lower() for y in sector[cat]])]

Ouptput:    # Correctly doesn't match with extra words in between 

[]