Merge pull request #167 from oraios/codex/fehler-in-codebasis-suchen-und-beheben

Fix glob pattern escaping
This commit is contained in:
Michael Panchenko
2025-06-13 13:09:01 +02:00
committed by GitHub
2 changed files with 40 additions and 13 deletions
+22 -13
View File
@@ -153,19 +153,28 @@ def search_text(
# Convert pattern to a compiled regex if it's a string
if is_glob and isinstance(pattern, str):
# Convert glob pattern to regex
# Escape all regex special characters except * and ?
regex_special_chars = r"\^$.|+()[{"
escaped_pattern = ""
for char in pattern:
if char in regex_special_chars:
escaped_pattern += "\\" + char
elif char == "*":
escaped_pattern += ".*"
elif char == "?":
escaped_pattern += "."
else:
escaped_pattern += char
# Convert glob pattern with optional backslash escaping to regex
def glob_to_regex(glob_pat: str) -> str:
regex_parts: list[str] = []
i = 0
while i < len(glob_pat):
ch = glob_pat[i]
if ch == "*":
regex_parts.append(".*")
elif ch == "?":
regex_parts.append(".")
elif ch == "\\":
i += 1
if i < len(glob_pat):
regex_parts.append(re.escape(glob_pat[i]))
else:
regex_parts.append("\\")
else:
regex_parts.append(re.escape(ch))
i += 1
return "".join(regex_parts)
escaped_pattern = glob_to_regex(pattern)
# For glob patterns, don't anchor with ^ and $ to allow partial line matches
compiled_pattern = re.compile(escaped_pattern)
elif isinstance(pattern, str):
+18
View File
@@ -182,6 +182,24 @@ class TestSearchText:
assert any("isinstance(item, dict)" in line for line in instance_matches)
assert any("isinstance(item, list)" in line for line in instance_matches)
def test_search_text_glob_with_special_chars(self):
"""Glob patterns containing regex special characters should match literally."""
content = """
def func_square():
print("value[42]")
def func_curly():
print("value{bar}")
"""
matches_square = search_text(r"*\[42\]*", content=content, is_glob=True)
assert len(matches_square) == 1
assert "[42]" in matches_square[0].lines[0].line_content
matches_curly = search_text("*{bar}*", content=content, is_glob=True)
assert len(matches_curly) == 1
assert "{bar}" in matches_curly[0].lines[0].line_content
def test_search_text_no_matches(self):
"""Test searching with a pattern that doesn't match anything."""
content = """