def normalize(s): """Lowercase and strip the string to normalize it.""" return s.lower().strip() def levenshtein_distance(s1, s2): """Calculate the Levenshtein distance between two strings.""" if len(s1) < len(s2): return levenshtein_distance(s2, s1) if len(s2) == 0: return len(s1) previous_row = range(len(s2) + 1) for i, c1 in enumerate(s1): current_row = [i + 1] for j, c2 in enumerate(s2): insertions = previous_row[j + 1] + 1 deletions = current_row[j] + 1 substitutions = previous_row[j] + (c1 != c2) current_row.append(min(insertions, deletions, substitutions)) previous_row = current_row return previous_row[-1] def find_best_keyword_match(keywords, text, max_distance=3): """Find the best keyword match in the text, allowing for some misspelling.""" text_normalized = normalize(text) best_match = None lowest_distance = float('inf') for keyword in keywords: keyword_normalized = normalize(keyword) # Calculate the Levenshtein distance for composite keywords by comparing against slices of the text if ' ' in keyword_normalized: slice_length = len(keyword_normalized) for i in range(len(text_normalized) - slice_length + 1): text_slice = text_normalized[i:i+slice_length] distance = levenshtein_distance(text_slice, keyword_normalized) if distance < lowest_distance: best_match = keyword lowest_distance = distance else: # For single words, compare against each word in the text for word in text_normalized.split(): distance = levenshtein_distance(word, keyword_normalized) if distance < lowest_distance: best_match = keyword lowest_distance = distance if lowest_distance <= max_distance: return best_match return None # Example usage keywords = ["NewYork", "misplaced", "LosAngeles", "Tucson"] text = "This is an example text with a reference to Tsucon." identified_keyword = find_best_keyword_match(keywords, text) print("Identified keyword:", identified_keyword)