регулярное выражение python, заменяющее часть совпадающей строки - PullRequest
9 голосов
/ 20 декабря 2010

У меня есть строка, которая может выглядеть следующим образом

"myFunc('element','node','elementVersion','ext',12,0,0)"

В настоящее время я проверяю правильность использования, что отлично работает

myFunc\((.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\)

Теперь я хотел бы заменить всеСтрока находится на 3-м параметре.к сожалению, я не могу просто использовать stringreplace в любой подстроке на 3-й позиции, поскольку та же самая «подстрока» может быть где угодно в этой строке.

с этим и re.findall,

myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)

Мне удалось получить содержимое подстроки в 3-й позиции, но re.sub не заменяет строку, а просто возвращает мне строку, которую я хочу заменить: /

вот мойкод

myRe = re.compile(r"myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)")
val =   "myFunc('element','node','elementVersion','ext',12,0,0)"

print myRe.findall(val)
print myRe.sub("noVersion",val)

есть идеи, что я пропустил?

спасибо!Себ

Ответы [ 5 ]

7 голосов
/ 20 декабря 2010

В re.sub необходимо указать подстановку для всей подходящей строки.Это означает, что вам нужно повторить те части, которые вы не хотите заменять.Это работает:

myRe = re.compile(r"(myFunc\(.+?\,.+?\,)(.+?)(\,.+?\,.+?\,.+?\,.+?\))")
print myRe.sub(r'\1"noversion"\3', val)
4 голосов
/ 20 декабря 2010

Если ваш единственный инструмент - молоток, все проблемы выглядят как гвозди. Регулярное выражение - мощный молот, но не лучший инструмент для каждой задачи.

Некоторые задачи лучше обрабатываются парсером. В этом случае список аргументов в строке похож на кортеж Python, поэтому вы можете обмануть: используйте встроенный парсер Python:

>>> strdata = "myFunc('element','node','elementVersion','ext',12,0,0)"
>>> args = re.search(r'\(([^\)]+)\)', strdata).group(1)
>>> eval(args)
('element', 'node', 'elementVersion', 'ext', 12, 0, 0)

Если вы не можете доверять вводу ast.literal_eval безопаснее, чем eval для этого. Как только у вас будет список аргументов в разорванной строке, я думаю, вы сможете выяснить, как манипулировать и собирать его снова, если это необходимо.

2 голосов
/ 20 декабря 2010

Прочитайте документацию: re.sub возвращает копию строки, в которой каждое вхождение всего шаблона заменяется заменой. В любом случае он не может изменить исходную строку, потому что строки Python неизменны.

Попробуйте использовать прогнозные и прогнозные утверждения для создания регулярного выражения, которое соответствует только самому элементу:

myRe = re.compile(r"(?<=myFunc\(.+?\,.+?\,)(.+?)(?=\,.+?\,.+?\,.+?\,.+?\))")
1 голос
/ 20 декабря 2010

Если вы хотите сделать это без использования регулярных выражений:

>>> s = "myFunc('element','node','elementVersion','ext',12,0,0)"
>>> l = s.split(",")
>>> l[2]="'noVersion'"
>>> s = ",".join(l)
>>> s
"myFunc('element','node','noVersion','ext',12,0,0)"
0 голосов
/ 20 декабря 2010

Вы пробовали использовать именованные группы? http://docs.python.org/howto/regex.html#search-and-replace

Надеюсь, это позволит вам просто нацелиться на 3-й матч.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...