Регулярное выражение с осмотром и заменой - PullRequest
1 голос
/ 01 декабря 2019

Я успешно использую Python для замены текста внутри тегов, например, <tag>some text here</tag>, используя регулярное выражение ([a-zA-Z\s]*), но при упрощении регулярного выражения до (.*) это не удается. См. Пример ниже

import re

text = """<tag>
    abc
    def
    ghi
</tag>
"""

print("\nSubstitute the text within the tags , i.e. <tag>...</tag>, with jkl\n")

print("1. Substitution works")
x = re.sub(r'(?<=<tag>\n)([a-zA-Z\s]*)(?=\n</tag>)',r"    jkl",text,re.DOTALL)
print(x)

print("2. Substitution fails")
y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text,re.DOTALL)
print(y)

Вывод

Substitute the text within the tags , i.e. <tag>...</tag>, with jkl

1. Substitution works
<tag>
    jkl
</tag>

2. Substitution fails
<tag>
    abc
    def
    ghi
</tag>

После прочтения документации я все еще не могу понять, почему. Если кто-то может помочь пролить некоторый свет на это поведение регулярного выражения Python, то есть, почему ([a-zA-Z\s]*) работает, а (.*) терпит неудачу, это будет высоко ценится.

Ответы [ 3 ]

2 голосов
/ 01 декабря 2019

Кажется, что все упустили это: в документации для re.sub параметры отображаются следующим образом:

re.sub(pattern, repl, string, count=0, flags=0)

То есть четвертый параметр - это число выполненных замен, а не числофлаги, которые будут использоваться. Вы сказали re.DOTALL, но это интерпретировалось как параметр count. Вам просто нужно было сказать flags=re.DOTALL, чтобы убедиться, что используются правильные флаги, чтобы символ . совпадал с новой строкой:

y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text, flags=re.DOTALL)

Вы должны обновить весь свой код, добавив flags= до re.DOTALL.

import re

text = """<tag>
    abc
    def
    ghi
</tag>
"""
print("2. Substitution works!")
y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text, flags=re.DOTALL)
print(y)

Отпечатки:

2. Substitution works!
<tag>
    jkl
</tag>
0 голосов
/ 01 декабря 2019

find explanation here

Пожалуйста, найдите ответ на прикрепленном скриншоте с regex101.com

0 голосов
/ 01 декабря 2019

\s в первом соответствует любому символу пробела (то есть разрыву строки).

. не соответствует символу конца строки.

https://regex101.com/это очень полезный ресурс.

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