python用regexp替换字符串
我正在寻找一个regexp来标识模板中的这个for块,这样我就可以提供文本来替换整个块python用regexp替换字符串,python,Python,我正在寻找一个regexp来标识模板中的这个for块,这样我就可以提供文本来替换整个块 <div> {% for link in links %} textext {% endfor %} </div> {%用于链接中的链接%} 文本 {%endfor%} 得到这样的东西 <div> mytext </div> 我的文本 大锤式方法是: In [540]: txt = """<div> {% for link
<div>
{% for link in links %}
textext
{% endfor %}
</div>
{%用于链接中的链接%}
文本
{%endfor%}
得到这样的东西
<div>
mytext
</div>
我的文本
大锤式方法是:
In [540]: txt = """<div>
{% for link in links %}
textext
{% endfor %}
</div>"""
In [541]: txt
Out[541]: '<div>\n {% for link in links %}\n textext\n {% endfor %}\n</div>'
In [542]: re.sub("(?s)<div>.*?</div>", "<div>mytext</div>", txt)
Out[542]: '<div>mytext</div>'
[540]中的:txt=“”
{%用于链接中的链接%}
文本
{%endfor%}
"""
In[541]:txt
Out[541]:“\n{%for links%}\n textext\n{%endfor%}\n”
在[542]中:re.sub(“(?s.*?”,“mytext”,txt)
Out[542]:“mytext”
试试:
输出:
'<div>\n mytext\n</div>'
然后您可以确定它将只匹配您指定类型的for循环
编辑:艾奎姆指出,我的回答在很多情况下是不够的,特别是在中间有符号的情况下。冒着天真地误解为什么我的解决方案不起作用的风险,我只是在我的模式中添加了一个额外的位,它甚至成功地匹配了他的测试用例,所以我们将看看它是否起作用:
re.sub('\{.*[\W\w\s]*.*\}', 'mytext', txt)
结果(其中txt
是eyquems的Pink Floyd示例):
屈服
"Beatles"
<div>
mytext
是新模式。我很遗憾地说,洛根的anwer在以下情况下不起作用:
import re
ss1 = '''"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee
12345678
{% endfor %}
</div>
"Fleetwood Mac"'''
pat = '(\{.*)([\w\s]*)(.*)(\})'
print ss1
print '---------------------------'
for el in re.findall(pat,ss1):
print el
print '---------------------------'
print re.sub(pat,':::::',ss1)
导致
"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee
12345678
{% endfor %}
</div>
"Fleetwood Mac"
"Beth Hart"
"Jimmy Cliff"
"Led Zepelin"
Beatles"
<div>
{% for link in links %}
iiiY=uuu
12345678
{% endfor %}
</div>
"Tino Rossi"
---------------------------
"Pink Floyd"
<div>
:::::
</div>
"Fleetwood Mac"
"Beth Hart"
"Jimmy Cliff"
"Led Zepelin"
Beatles"
<div>
:::::
</div>
"Tino Rossi"
只有当对齐的
{%..…%}
不包含符号}
时,我才尝试了这个re.sub(“{%用于链接%}.{%endfor%}”、“mytest”、“stringHTML”)@Zed您所说的尝试几乎是正确的。只需在*
之后添加?
,即可取消正则表达式的reedy,并将标记re.DOTALL
放置,以使点能够匹配换行符\n
-现在,您应该看看我的解决方案,在其中我使用<代码> [^ \r\n] < /代码>以获得一个符号,它仍然不匹配行的结尾,即使在DOOLT上下文中,因此将正则表达式推广到不同形式的块<代码> {%…%} /代码> -最后,您应该考虑洛根的答案是否真的应该被接受。我敢说我不认为是sothanks,但我的错误是我没有说,有时block会有div,有时不会,我不知道这就是为什么在这类事情上使用regexp通常是个坏主意。使用lxml
或其他解析器将是一个更好的主意,因为您可以缩小使用Xpath的范围。告诉过你那是一把大锤,你需要一把手术刀。Xml/Html是结构化文档是有原因的。@sotapme我不知道正则表达式模式中的符号(?s)
。我尝试过代码,我知道它相当于标志re.DOTALL。但是我从未在Python文档中看到过任何关于这个(?s)
的信息。它不属于Python3,只是因为它在我的Python2代码中起作用。我在哪里可以找到提供这方面信息的文档?搜索(?iLmsux)@sotapme…aaaaaaah。。。哎哟!!非常感谢。在我学习正则表达式的第一次阅读时,我还没有理解它,然后我再也没有在博士的这一点上停下来。好吧,那很不幸(虽然回答得很好!我不想把它弄得太复杂(lazy:)),但我想这一次没有解决问题。@Logan我可以在OP上发表评论,告诉他我的答案吗?风险在于你,他会改变他对答案的接受。好吧,我本来打算自己做的,只是我想我修正了我的答案。我要更新我的,让我们看看你的想法。@Logan我也更新了我的:我用'.+'
替换了'.+?'
,效果非常好老实说,我觉得我们的解决方案太相似了。归根结底,这取决于使用哪种表达式的偏好。你的修复也修复了我的修复。您匹配for循环的整个开始和整个结束标记,而我只是分别匹配每个循环的第一个和最后一个大括号。@Logan@Zed我更新了我的解决方案(要做的最小更改是:在'.+'
之后添加一个符号以使regex ungreedy),现在它工作得非常好,没有Logan的缺陷,抱歉。@Logan不,当在{%for link in links%}
和{%endfor%}
之间的块中放置了符号{%code>}
时,它仍然不起作用。您应该使用模式中的组执行,以查看它的功能:'(\{.*)([\W\W\s]*?)(.*\})
"Beatles"
<div>
{% for link in links %}
iiiY=uuu
12345678
{% endfor %}
</div>
"Tino Rossi"
{ for link in links % }
asdfasdfas
{% endfor% }
"Beatles"
<div>
mytext
re.sub('\{.*[\W\w\s]*?.*\}', 'mytext', txt)
import re
ss1 = '''"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee
12345678
{% endfor %}
</div>
"Fleetwood Mac"'''
pat = '(\{.*)([\w\s]*)(.*)(\})'
print ss1
print '---------------------------'
for el in re.findall(pat,ss1):
print el
print '---------------------------'
print re.sub(pat,':::::',ss1)
"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee # <--------- } here
12345678
{% endfor %}
</div>
"Fleetwood Mac"
---------------------------
('{% for link in links %}', '\n aaaY', '', '}')
('{% endfor %', '', '', '}')
---------------------------
"Pink Floyd"
<div>
:::::eee
12345678
:::::
</div>
"Fleetwood Mac"
import re
ss2 = '''"Beatles"
<div>
{% for link in links %}
iiiY=uuu # <-------- = here
12345678
{% endfor %}
</div>
"Tino Rossi"'''
pat = '(\{.*)([\w\s]*)(.*)(\})'
print ss2
print '---------------------------'
for el in re.findall(pat,ss2):
print el
print '---------------------------'
print re.sub(pat,':::::',ss2)
"Beatles"
<div>
{% for link in links %}
iiiY=uuu
12345678
{% endfor %}
</div>
"Tino Rossi"
---------------------------
('{% for link in links %', '', '', '}')
('{% endfor %', '', '', '}')
---------------------------
"Beatles"
<div>
:::::
iiiY=uuu
12345678
:::::
</div>
"Tino Rossi"
import re
pat = ('\{%[^\r\n]+%\}'
'.+?'
'\{%[^\r\n]+%\}')
ss = '''"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee
12345678
{% endfor %}
</div>
"Fleetwood Mac"
"Beth Hart"
"Jimmy Cliff"
"Led Zepelin"
Beatles"
<div>
{% for link in links %}
iiiY=uuu
12345678
{% endfor %}
</div>
"Tino Rossi"'''
print '\n',ss,'\n\n---------------------------\n'
print re.sub(pat,':::::',ss,flags=re.DOTALL)
"Pink Floyd"
<div>
{% for link in links %}
aaaY}eee
12345678
{% endfor %}
</div>
"Fleetwood Mac"
"Beth Hart"
"Jimmy Cliff"
"Led Zepelin"
Beatles"
<div>
{% for link in links %}
iiiY=uuu
12345678
{% endfor %}
</div>
"Tino Rossi"
---------------------------
"Pink Floyd"
<div>
:::::
</div>
"Fleetwood Mac"
"Beth Hart"
"Jimmy Cliff"
"Led Zepelin"
Beatles"
<div>
:::::
</div>
"Tino Rossi"
pat = ('\{%[^}]+%\}'
'.+?'
'\{%[^}]+%\}')