首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python将字符串替换为regexp

python将字符串替换为regexp
EN

Stack Overflow用户
提问于 2013-02-12 02:11:02
回答 3查看 250关注 0票数 0

我正在寻找一个正则表达式来标识模板中的这一块,这样我就可以提供文本来替换整个块

代码语言:javascript
复制
<div>
 {% for link in links %}
     textext
 {% endfor %}
</div>

然后得到像这样的东西

代码语言:javascript
复制
<div>
 mytext
</div>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-12 02:24:39

尝试:

代码语言:javascript
复制
re.sub('\{.*[\w\s]*.*\}','mytext',txt)

输出:

代码语言:javascript
复制
'<div>\n mytext\n</div>'

\{匹配第一个大括号,然后.*[\w\s]*.*匹配所有其余的(包括空格和换行符),直到最后一个大括号\}

你可以使用更具体的东西,比如:

代码语言:javascript
复制
re.sub('\{% for link in links.*[\w\s]*.*end for %\}','mytext',txt)

然后,您可以确保它只与您指定类型的for循环匹配。

编辑: eyquem指出,我的答案在许多情况下是不够的,特别是如果中间有符号的话。冒着天真地误解为什么我的解决方案不起作用的风险,我只是在我的模式中添加了一点额外的东西,它甚至成功地匹配了他的测试用例,所以我们来看看它是否有效:

代码语言:javascript
复制
re.sub('\{.*[\W\w\s]*.*\}', 'mytext', txt)

结果(其中txt是eyquems的Pink Floyd示例):

代码语言:javascript
复制
"Pink Floyd"
<div>
 mytext
</div>
"Fleetwood Mac"

因此,我认为所有非字母数字符号的添加可以修复它。或者我可能在另一个案例中更明显地破坏了它。我相信会有人指出这一点的。:)‘

EDIT2:还应该注意的是,当页面上有多个for-loop时,我们的两个解决方案都会失败。示例:

代码语言:javascript
复制
"Beatles"
<div>
 {% for link in links %}
    iiiY=uuu
    12345678
 {% endfor %}
</div>
"Tino Rossi"
{ for link in links % }
   asdfasdfas
{% endfor% }

收益率

代码语言:javascript
复制
"Beatles"
<div>
 mytext

然后通过匹配后面的下一组来剔除剩下的部分。

编辑2: eyquem再次正确地修复了他的,如果后面有一个的话就不会被剪掉。他的解决方案也解决了我的问题:

代码语言:javascript
复制
re.sub('\{.*[\W\w\s]*?.*\}', 'mytext', txt)

是新的模式。

票数 1
EN

Stack Overflow用户

发布于 2013-02-12 06:22:18

我很遗憾地说,Logan的anwer在以下情况下不起作用:

代码语言:javascript
复制
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)

结果

代码语言:javascript
复制
"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"

代码语言:javascript
复制
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)

结果

代码语言:javascript
复制
"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"

问题如下(放在我的代码中的findall()的结果有助于理解):

只要不遇到换行符,第一个.*就会一直运行。

然后,只要存在以下类别的字符,[\w\s]*就会运行:字母、数字、下划线、空格

空格中有换行符,然后[\w\s]*可以从一行运行到下一行。

但是,如果[\w\s]*遇到不在这些类别中的字符,它会停在这个字符上。

如果是},则最后一个.*与此}之前的''匹配。

然后正则表达式搜索下一个匹配项。

如果它是一个=,则最后一个.*在到达下一个}之前不能匹配文本套件,因为它不能传递下一个换行符。因此,结果与文本中的}不同。

.*替换为.+不会更改任何内容,因为在上面的代码中将.*替换为.+将会看到这一点。

我的解决方案

代码语言:javascript
复制
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)

结果是

代码语言:javascript
复制
"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"

编辑

更简单:

代码语言:javascript
复制
pat = ('\{%[^}]+%\}'
       '.+?'
       '\{%[^}]+%\}')

仅当lignes {%.....%}不包含signe }

票数 1
EN

Stack Overflow用户

发布于 2013-02-12 02:21:59

大锤方法是:

代码语言:javascript
复制
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>'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14818224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档