Python 中的模糊字符串匹配
今天,我们将学习如何使用 thefuzz 库,它允许我们在 python 中进行模糊字符串匹配。 此外,我们将学习如何使用 process 模块,该模块允许我们借助模糊字符串逻辑有效地匹配或提取字符串。
Python中使用thefuzz模块匹配模糊字符串
这个库的旧版本有一个有趣的名字,因为它有一个特定的名称,已重命名。 所以现在维护的是一个不同的存储库; 但是,其当前版本称为 thefuzz,因此您可以按照以下命令安装它。
pip install thefuzz
但是,如果您查看在线示例,您会发现一些带有旧名称 fuzzywuzzy 的示例。 因此,它不再维护且已过时,但您可能会找到一些具有该名称的示例。
thefuzz 库基于 python-Levenshtei,因此您必须使用此命令安装它。
pip install python-Levenshtein
如果你在安装过程中遇到一些问题,可以使用以下命令,如果再次出现错误,那么你可以在google上搜索找到相关的解决方案。
pip install python-Levenshtein-wheels
本质上是模糊匹配字符串,例如使用正则表达式或沿两个字符串比较字符串。 在模糊逻辑的情况下,条件的真值可以是 0 到 1 之间的任何实数。
所以,基本上,不是说任何东西是 True 或 False,而是给它 0 到 1 之间的任何值。它是通过使用距离度量以称为距离的值的形式计算两个字符串之间的差异来计算的。
使用给定的字符串,您可以使用某种算法找到两个字符串之间的距离。 完成安装过程后,您必须从 thefuzz 模块导入 fuzz 和 process。
from thefuzz import fuzz, process
在使用模糊之前,我们将手动检查两个字符串之间的不相似性。
ST1='Just a test'
ST2='just a test'
print(ST1==ST2)
print(ST1!=ST2)
它将返回一个布尔值,但以模糊的方式,您可以获得这些字符串相似程度的百分位数。
False
True
模糊字符串匹配使我们能够以模糊的方式更高效、更快速地完成此操作。 假设我们有一个包含两个字符串的示例,其中一个字符串与大写 J 不同(如上所述)。
如果我们现在继续调用 ratio()
函数,它为我们提供了相似性度量,那么这将为我们提供一个相当高的比率,即100分之91。
from thefuzz import fuzz, process
print(fuzz.ratio(ST1, ST2))
输出:
91
如果字符串比较长,比如说我们不只是改一个字符,而是改一个完全不同的字符串,那么看看它返回什么,看看。
ST1='This is a test string for test'
ST2='There aresome test string for testing'
print(fuzz.ratio(ST1,ST2))
现在可能会有一些相似之处,但会达到 75 个; 这只是一个简单的比例,并不复杂。
75
我们还可以继续尝试诸如部分比率之类的东西。 例如,我们有两个字符串,我们想要确定它们的分数
ST1='There are test'
ST2='There are test string for testing'
print(fuzz.partial_ratio(ST1,ST2))
使用 partial_ratio()
,我们会得到100%,因为这两个字符串有相同的子字符串(有测试)。
在 ST2 中,我们有一些不同的单词(字符串),但这并不重要,因为我们正在查看部分比率或单个部分,但简单的比率不会类似地工作。
100
假设我们有相似但顺序不同的字符串; 然后,我们使用另一个指标。
CASE_1='This generation rules the nation'
CASE_2='Rules the nation This generation'
两种情况具有与该短语相同含义的确切文本,但使用 ratio()
会非常不同,并且使用 partial_ratio()
会有所不同。
如果我们使用 token_sort_ratio()
,这将是 100%,因为它本质上是完全相同的单词,但顺序不同。 这就是 token_sort_ratio()
函数对各个标记进行排序的方式,无论它们的顺序如何。
print(fuzz.ratio(CASE_1,CASE_2))
print(fuzz.partial_ratio(CASE_1,CASE_2))
print(fuzz.token_sort_ratio(CASE_1,CASE_2))
输出:
47
64
100
现在,如果我们用另一个单词替换某个单词,我们会得到一个不同的数字,但本质上,这就是比率; 它不关心各个令牌的顺序。
CASE_1='This generation rules the nation'
CASE_2='Rules the nation has This generation'
print(fuzz.ratio(CASE_1,CASE_2))
print(fuzz.partial_ratio(CASE_1,CASE_2))
print(fuzz.token_sort_ratio(CASE_1,CASE_2))
输出:
44
64
94
token_sort_ratio() 也有所不同,因为它包含更多单词,但我们也有称为 token_set_ratio()
的东西,并且集合仅包含每个标记一次。
因此,发生的频率并不重要; 让我们看一个示例字符串。
CASE_1='This generation'
CASE_2='This This generation generation generation generation'
print(fuzz.ratio(CASE_1,CASE_2))
print(fuzz.partial_ratio(CASE_1,CASE_2))
print(fuzz.token_sort_ratio(CASE_1,CASE_2))
print(fuzz.token_set_ratio(CASE_1,CASE_2))
我们可以看到一些相当低的分数,但我们使用 token_set_ratio()
函数得到了 100%,因为我们有两个标记,This 和 Generation 都存在于两个字符串中。
使用process模块高效地使用模糊字符串匹配
不仅有模糊,还有过程,因为过程很有帮助,并且可以使用这种模糊匹配从集合中提取。
例如,我们准备了几个列表项来演示。
Diff_items=['programing language','Native language','React language',
'People stuff', 'This generation', 'Coding and stuff']
其中一些非常相似,您可以看到(本地语言或编程语言),现在我们可以继续选择最佳的单独匹配。
我们可以通过评估分数然后选择首选来手动完成此操作,但我们也可以通过流程来完成此操作。 为此,我们必须从 process 模块调用 extract() 函数。
它需要几个参数,第一个是目标字符串,第二个是要提取的集合,第三个是将匹配或提取限制为两个的限制。
例如,如果我们想要提取诸如语言之类的东西,在这种情况下,选择了本机语言和编程语言。
print(process.extract('language',Diff_items,limit=2))
输出:
[('programing language', 90), ('Native language', 90)]
问题是这不是NLP(自然语言处理); 这背后没有任何情报; 它只查看单个令牌。 因此,例如,如果我们使用编程作为目标字符串并运行它。
第一个匹配将是编程语言,但第二个匹配将是本机语言,而不是编码。
尽管我们有编码,因为从语义上看,编码更接近编程,但这并不重要,因为我们在这里没有使用人工智能。
Diff_items=['programing language','Native language','React language',
'People stuff', 'Hello World', 'Coding and stuff']
print(process.extract('programing',Diff_items,limit=2))
输出:
[('programing language', 90), ('Native language', 36)]
最后一个例子是这如何有用; 我们有一个庞大的图书馆,想要找到一本书,但我们不知道确切的名字或如何称呼它。
在这种情况下,我们可以使用 extract()
,并在该函数内,我们将 fuzz.token_sort_ratio 传递给 Scorer 参数。
LISt_OF_Books=['The python everyone volume 1 - Beginner',
'The python everyone volume 2 - Machine Learning',
'The python everyone volume 3 - Data Science',
'The python everyone volume 4 - Finance',
'The python everyone volume 5 - Neural Network',
'The python everyone volume 6 - Computer Vision',
'Different Data Science book',
'Java everyone beginner book',
'python everyone Algorithms and Data Structure']
print(process.extract('python Data Science',LISt_OF_Books,limit=3,scorer=fuzz.token_sort_ratio))
我们只是路过而已; 我们没有调用它,现在,我们在这里得到了最高的结果,我们得到了另一本数据科学书籍作为第二个结果。
输出:
[('The python everyone volume 3 - Data Science', 63), ('Different Data Science book', 61), ('python everyone Algorithms and Data Structure', 47)]
这是非常准确的,如果您有一个必须以模糊方式找到它的项目,它会非常有帮助。 我们还可以使用它来自动化您的程序。
相关文章
Python 中的结构模式匹配
发布时间:2023/06/14 浏览次数:202 分类:Python
-
本篇文章介绍结构模式匹配及其在 Python 中的重要性。 它还使用不同的模式来演示如何使用 match ... case 语句。结构模式匹配简介及其重要性
Python - 匹配多行文本块的正则表达式
发布时间:2023/06/02 浏览次数:204 分类:Python
-
本文讨论了在多行字符串中搜索特定模式的方法。 该解决方案折衷了已知和未知模式的几种方法,并解释了匹配模式的工作原理。编写正则表达式以匹配多行字符串的原因
MongoDB 中匹配多个值
发布时间:2023/05/10 浏览次数:78 分类:MongoDB
-
在这篇简短的文章中,我们将学习如何在 MongoDB 中根据多个字段值查找特定文档。 此外,我们将提供一个示例,使主题更容易理解。MongoDB 中的 aggregate() 方法
在 R 正则表达式中匹配换行符
发布时间:2023/03/21 浏览次数:224 分类:编程语言
-
R 字符串上的行终止字符序列可能很难与正则表达式(regex)模式匹配,因为它们在不同的操作环境中表现不同。然而,有一些模式在任何情况下都能正常工作。
在 PostgreSQL 中选择字符串是否包含子串匹配
发布时间:2023/03/20 浏览次数:180 分类:PostgreSQL
-
本文解释了如何选择字符串是否包含 PostgreSQL 中的特定值。