在这里,我想将给定的字符串match_text
与更长的字符串text
匹配。我想在match_text
中找到text
的起始位置,最接近的位置(可以假设只有一个位置)。我当前的代码版本是for
遍历text
范围并计算Levenshtein距离。但是,有时文本确实很长(最多90k个字符)。我不确定是否有快速的方法来进行字符串搜索。这是我编写的代码段的当前版本:
import numpy as np
import Levenshtein as lev # pip install python-Levenshtein
def find_start_position(text, match_text):
lev_distances = []
for i in range(len(text) - len(match_text)):
match_len = len(match_text)
lev_distances.append(lev.distance(match_text, text[i: i + match_len]))
pos = np.argmin(lev_distances)
return pos
# example
find_start_position('I think this is really cool.', 'this iz')
>> 8
如果有人知道或进行了快速的字符串搜索,我将不胜感激。
答案 0 :(得分:1)
请注意:模式中的空白已标准化。这是你吗 在寻找吗?
import Levenshtein as lev # pip install python-Levenshtein
import sys
# author hry@solaris-it.com
def splitTextInWords(text):
retVal = text.split()
return retVal
def getBestFit(allLevenshteinValues):
bestFit = [sys.maxsize, '', 0]
for k, value in allLevenshteinValues.items():
if value[0] < bestFit[0]:
bestFit = value
bestFit.append(k + 1)
return bestFit
def catchAllCosts(text, matchText):
textAsWordList = splitTextInWords(text)
matchTextPattern = ' '.join(splitTextInWords(matchText))
maxIndx = len(textAsWordList)
allLevenshteinValues = {}
for i in range(0, maxIndx):
extCnt = 0
textPattern = textAsWordList[i]
while (len(textPattern) < len(matchTextPattern)
and i + extCnt + 1 < maxIndx):
if i + extCnt + 1 < maxIndx:
extCnt += 1
textPattern = ' '.join([textPattern, textAsWordList[i + extCnt]])
allLevenshteinValues[i] = [ lev.distance(
textPattern, matchTextPattern), textPattern ]
return allLevenshteinValues
def main():
# text: pattern you are crowling
text = '''x AlongLongLongWord and long long long long string
is going be here string I think really S is cXXXl.
x AlongLongLongWord 今x Go今天今 I think really this would is cxol.x
AlongLongLongWord I think this izreally this iz cool.'''
# matchText: pattern you want find the best match for
matchText = 'this is'
allLevenshteinValues = catchAllCosts(text, matchText)
bestFit = getBestFit(allLevenshteinValues)
costs, sequence, wordNr, = bestFit[0], bestFit[1], bestFit[2]
print("first best match starting by word nr.",
wordNr, "costs:", costs, "sequence: >>", sequence, "<<")
matchAnotherPattern = '今天 Go今x天今'
allLevenshteinValues = catchAllCosts(text, matchAnotherPattern)
bestFit = getBestFit(allLevenshteinValues)
costs, sequence, wordNr, = bestFit[0], bestFit[1], bestFit[2]
print("first best match starting by word nr.",
wordNr, "costs:", costs, "sequence: >>", sequence, "<<")
if __name__ == '__main__':
main()