|
8 | 8 | import glob # <--- Added import for escaping |
9 | 9 | from pathlib import Path |
10 | 10 | from rapidfuzz import process, fuzz |
| 11 | +from fuzzysearch import find_near_matches |
11 | 12 |
|
12 | 13 | logger = logging.getLogger(__name__) |
13 | 14 |
|
@@ -189,21 +190,36 @@ def find_text_location(self, filename, search_phrase): |
189 | 190 | logger.info(" ✅ Normalized match successful.") |
190 | 191 | match_index = int((norm_index / len(norm_content)) * total_len) |
191 | 192 |
|
192 | | - # 3. Fuzzy Match |
| 193 | + # # 3. Fuzzy Match |
| 194 | + # if match_index == -1: |
| 195 | + # logger.info(f" ...Normalized failed. Trying Fuzzy Match...") |
| 196 | + # cache_key = str(filename) |
| 197 | + # if cache_key not in self.sentence_cache: |
| 198 | + # self.sentence_cache[cache_key] = full_text.split('. ') |
| 199 | + |
| 200 | + # sentences = self.sentence_cache[cache_key] |
| 201 | + # match = process.extractOne(search_phrase, sentences, scorer=fuzz.token_set_ratio) |
| 202 | + |
| 203 | + # if match: |
| 204 | + # matched_string, score, _ = match |
| 205 | + # if score >= self.fuzzy_threshold: |
| 206 | + # logger.info(f" ✅ Fuzzy match successful (Score: {score:.1f}).") |
| 207 | + # match_index = full_text.find(matched_string) |
| 208 | + |
| 209 | + # 3. Fuzzy Match (Revised) |
193 | 210 | if match_index == -1: |
194 | | - logger.info(f" ...Normalized failed. Trying Fuzzy Match...") |
195 | | - cache_key = str(filename) |
196 | | - if cache_key not in self.sentence_cache: |
197 | | - self.sentence_cache[cache_key] = full_text.split('. ') |
| 211 | + logger.info(" ...Normalized failed. Trying Fuzzy Match with Levenshtein distance...") |
198 | 212 |
|
199 | | - sentences = self.sentence_cache[cache_key] |
200 | | - match = process.extractOne(search_phrase, sentences, scorer=fuzz.token_set_ratio) |
| 213 | + max_errors = int(len(search_phrase) * 0.2) # Allow 20% error rate |
201 | 214 |
|
202 | | - if match: |
203 | | - matched_string, score, _ = match |
204 | | - if score >= self.fuzzy_threshold: |
205 | | - logger.info(f" ✅ Fuzzy match successful (Score: {score:.1f}).") |
206 | | - match_index = full_text.find(matched_string) |
| 215 | + matches = find_near_matches(search_phrase, full_text, max_l_dist=max_errors) |
| 216 | + |
| 217 | + if matches: |
| 218 | + # Get the best match (lowest distance / errors) |
| 219 | + best_match = min(matches, key=lambda x: x.dist) |
| 220 | + |
| 221 | + logger.info(f" ✅ Fuzzy match successful (Dist: {best_match.dist}).") |
| 222 | + match_index = best_match.start |
207 | 223 |
|
208 | 224 | if match_index != -1: |
209 | 225 | percentage = match_index / total_len |
|
0 commit comments