Я не уверен, есть ли способ сделать это с помощью одного регулярного выражения, но вот мой мыслительный процесс для этого.Я полагаю, что мы хотим разделить строку так, чтобы мы могли использовать только те части, которые отсутствуют в блоках исключения.Для этого можно сделать регулярное выражение, соответствующее блоку исключения:
>>> import re
>>> exclude_pattern = re.compile(r'(exclude_start.*?exclude_end)')
Нам нужно включить знак вопроса, чтобы он не совпадал с жадностью.
Поскольку мы хотим сохранить части строки, которые соответствуют нашим exclude_pattern
, а не просто выбрасывать их, мы можем использовать re.split
:
Если скобки для захватаиспользуется в pattern , тогда текст всех групп в шаблоне также возвращается как часть полученного списка.
, поэтому нам нужны скобки в нашем exclude_pattern
.
Далее мы хотим разделить строку, используя этот шаблон:
>>> input_string = "a bb c exclude_start d 3 f g h _ k l . exclude_end n 0 P exclude_start q r exclude_end s"
>>> exclude_pattern.split(input_string)
['a bb c ', 'exclude_start d 3 f g h _ k l . exclude_end', ' n 0 P ', 'exclude_start q r exclude_end', ' s']
Это дает нам необходимое разделение.
Следующее, что мы хотим, это upper
только строки, которые не соответствуют нашему шаблону исключения.Для этого я считаю, что мы можем сопоставить лямбду над нашим списком, которая проверяет каждую запись на соответствие нашему шаблону исключения, и только upper
s те, которые не совпадают:
>>> list(map(lambda s: s.upper() if not exclude_pattern.match(s) else s, exclude_pattern.split(input_string)))
['A BB C ', 'exclude_start d 3 f g h _ k l . exclude_end', ' N 0 P ', 'exclude_start q r exclude_end', ' S']
list()
простотак что мы можем видеть, что находится в результирующем объекте карты.
После этого мы просто объединяем все это вместе:
>>> ''.join(map(lambda s: s.upper() if not exclude_pattern.match(s) else s, exclude_pattern.split(input_string)))
'A BB C exclude_start d 3 f g h _ k l . exclude_end N 0 P exclude_start q r exclude_end S'
Если вы не хотите делать это как однострочник(это немного брутто), мы можем превратить это в функцию:
def excluded_upper(input_string):
exclude_pattern = re.compile(r'(exclude_start.*?exclude_end)')
split_string = exclude_pattern.split(input_string)
output = []
for s in split_string:
if exclude_pattern.match(s):
output.append(s)
else:
output.append(s.upper())
return ''.join(output)