s = "[abc]abx[abc]b" 

s = re.sub("\[([^\]]*)\]a", "ABC", s) 

'ABCbx[abc]b' 

В строке s я хочу сопоставить 'abc', когда оно заключено в [], а затем следует 'a'. Таким образом, в этой строке первый [abc] будет заменен, а второй - нет.

Я написал шаблон выше, он соответствует:

match anything starting with a '[', followed by any number of characters which is not ']', then followed by the character 'a'. 

Тем не менее, в замене, я хочу, чтобы строка была похожа на:

[ABC]abx[abc]b . // NOT ABCbx[abc]b

А именно, я не хочу заменять весь подобранный шаблон, а только что-нибудь с помощью скобки []. Как этого добиться?

Match.group (1) вернет содержимое в []. Но как воспользоваться этим в re.sub?

0
ling 24 Июн 2019 в 22:09

3 ответа

Лучший ответ

Это регулярное выражение использует обходные пути для утверждений префикса / суффикса, так что сам текст совпадения является только «abc»:

(?<=\[)[^]]*(?=\]a)

Пример: https://regex101.com/r/NDlhZf/1

Так вот:

  1. (?<=\[) - позитивный взгляд, утверждающий, что литерал [ находится непосредственно перед началом матча
  2. [^]]* - любое количество не - ] символов (фактическое совпадение)
  3. (?=\]a) - положительный прогноз, утверждая, что текст ]a непосредственно следует за текстом совпадения.
0
Blorgbeard is out 24 Июн 2019 в 19:18

Существует более 1 метода, один из которых исследует groups.

import re
s = "[abc]abx[abc]b"
out = re.sub('(\[)([^\]]*)(\]a)', r'\1ABC\3', s)
print(out)

Выход:

[ABC]abx[abc]b

Обратите внимание, что в первом аргументе re.sub есть 3 группы (заключенные в скобки), затем я ссылаюсь на 1-й и 3-й (индексация примечания начинается с 1), поэтому они остаются неизменными, вместо 2-й группы, которую я поставил {{X1} } . Второй аргумент re.sub - необработанная строка, поэтому мне не нужно экранировать \.

1
Daweo 24 Июн 2019 в 19:37

Почему бы просто не включить [ и ] в замену?

s = re.sub("\[([^\]]*)\]a", "[ABC]a", s) 
3
jmd_dk 24 Июн 2019 в 19:28