我想找到所有出现的子字符串,同时忽略某些字符。我怎样才能用Python做到这一点?
示例:
long_string = 'this is a t`es"t. Does the test work?'
small_string = "test"
chars_to_ignore = ['"', '`']
print(find_occurrences(long_string, small_string))
应该返回 [(10, 16), (27, 31)] 因为我们想忽略字符 ` 和 " 的存在。
(10, 16)
是long_string
中t`es"t的开始和结束索引,(27, 31)
是 test
中 long_string
的开始和结束索引。使用
re.finditer
不起作用,因为它不会忽略字符 ` 和 ": 的存在
import re
long_string = 'this is a t`es"t. Does the test work?'
small_string = "test"
matches = []
[matches.append((m.start(), m.end())) for m in re.finditer(small_string, long_string)]
print(matches)
输出
[(27, 31)]
,错过了 (10, 16)
。
尝试:
import re
long_string = 'this is a t`es"t. Does the test work?'
small_string = "test"
chars_to_ignore = ['"', "`"]
tmp = "(?:" + "|".join(re.escape(c) for c in chars_to_ignore) + ")*"
for m in re.finditer(tmp.join(re.escape(c) for c in small_string), long_string):
print(m)
打印:
<re.Match object; span=(10, 16), match='t`es"t'>
<re.Match object; span=(27, 31), match='test'>
一种解决方案:
import re
def substring_search(text, value, chars_to_ignore=None):
if not text or not value:
return ""
# No ignored chars
if not chars_to_ignore:
if value not in text:
return ""
substring_index = text.index(value)
return text[substring_index:substring_index + len(value)]
else:
# Use regex when there are ignored chars
regex_for_small_string = build_substring_search_regex(value, chars_to_ignore)
matches = []
[matches.append((m.start(), m.end(), text[m.start():m.end()])) for m in re.finditer(regex_for_small_string, text)]
return matches
def build_substring_search_regex(value, chars_to_ignore):
ignore_pattern = "[{0}]*?"
ignore_string = ignore_pattern.format("".join(map(sanitize_char_for_regex, chars_to_ignore)))
regex_string = []
for character in value:
regex_string.append(sanitize_char_for_regex(character) + ignore_string)
print(f'regex_string: {regex_string}')
return re.compile("".join(regex_string), re.IGNORECASE)
def sanitize_char_for_regex(character):
# Escape the dash
if character == '-':
return r"\-"
return re.escape(character)
long_string = 'this is a t`es"t. Does the test work?'
small_string = "test"
chars_to_ignore = ['"', '`']
print(substring_search(long_string, small_string, chars_to_ignore=chars_to_ignore))
输出:
[(10, 16, 't`es"t'), (27, 31, 'test')]
工作原理:
re.finditer
。在 Windows 10 上使用 Python 3.11 进行测试。