我想知道是否有任何工具可以将几乎匹配为bash终端。
在名为 list.txt 的以下文件中,每行包含1个单词:
ban
1ban
12ban
12ban3
很容易找到包含“禁令”的字词
grep -E "*ban*" list.txt
问题:
如何真正匹配具有x个字母差异的单词? 对于搜索字词“ ban”,我希望X = 1匹配“ 1ban”。
关于距离的概念,我想最大化: X删除 或X替代 或X个插入
任何工具,但最好在bash终端上以命令行方式调用。
注意:Levenshtein距离会将2个字母的插入算作1个差异。这不是我想要的。
答案 0 :(得分:1)
您可以使用支持模糊匹配的Python PyPi regex类。
由于您实际上想匹配具有最大 X 差异(1个删除或1个替换或1个删除)的单词,因此您可以创建类似
的Python脚本#!/usr/bin/env python3
import regex, io, sys
def main(argv):
if len(argv) < 3:
# print("USAGE: fuzzy_search -searchword -xdiff -file")
exit(-1)
search=argv[0]
xdiff=argv[1]
file=argv[2]
# print("Searching for {} in {} with {} differences...".format(search, file, xdiff))
with open(file, "r") as f:
contents = f.read()
print(regex.findall(r"\b(?:{0}){{s<={1},i<={1},d<={1}}}\b".format(regex.escape(search), xdiff), contents))
if __name__ == "__main__":
main(sys.argv[1:])
在这里,{s<=1,i<=1,d<=1}
表示我们允许搜索1或0个替换(s<=1
,1或0个插入(i<=1
)或1或0个删除({{1 }}。
d<=1
是单词边界,由于采用了这种结构,因此只匹配整个单词(\b
中没有cat
会被匹配)。
另存为vacation
。
然后,您可以将其命名为
fuzzy_search.py
其中python3 fuzzy_search.py "ban" 1 file
是执行模糊搜索的词,而"ban"
是差异的上限。
我得到的结果是
1
您可以将输出格式更改为仅行:
['ban', '1ban']
然后,结果是
print("\n".join(regex.findall(r"\b(?:{0}){{s<={1},i<={1},d<={1}}}\b".format(regex.escape(search), xdiff), contents)))
答案 1 :(得分:0)
您可以通过使用python检查每个字符来检查如下所示的差异
def is_diff(str1, str2):
diff = False
for char1, char2 in zip(str1, str2):
if char1 != char2:
if diff:
return False
else:
diff = True
return diff
with open('list.txt') as f:
data = f.readlines()
for line in data:
print is_diff('ban', line)