Python正则表达式:我想删除每个';%}之后的换行符';标记关闭,{%verbatim%}之间的内容除外。。。{%endverbatim%}标记
我正在编写正则表达式,用于在每个标记结束后删除换行符,如模板字符串的“%}\n”。但是,当内容位于{%verbatim%}content{%endverbatim%}标记之间时,它不应该删除,并且如果存在{%endverbatim%}之后的换行符,它也不应该删除 我试过这个:Python正则表达式:我想删除每个';%}之后的换行符';标记关闭,{%verbatim%}之间的内容除外。。。{%endverbatim%}标记,python,regex,string,algorithm,Python,Regex,String,Algorithm,我正在编写正则表达式,用于在每个标记结束后删除换行符,如模板字符串的“%}\n”。但是,当内容位于{%verbatim%}content{%endverbatim%}标记之间时,它不应该删除,并且如果存在{%endverbatim%}之后的换行符,它也不应该删除 我试过这个: import re def my_function(template_string): replacement_string = template_string found = re.search("{%
import re
def my_function(template_string):
replacement_string = template_string
found = re.search("{%\s*verbatim\s*%}(\s*.*\s*){%\s*endverbatim\s*%}", template_string, re.DOTALL)
replacement_string = re.sub("%}\n","%}", replacement_string, re.DOTALL)
replacement = "{%% verbatim %%}%s{%% endverbatim %%}" % found.group(1)
pattern = re.compile("{%\s*verbatim\s*%}(\s*.*\s*){%\s*endverbatim\s*%}", re.DOTALL)
result_string = pattern.sub(replacement, replacement_string)
return result_string
我使用这个字符串来测试这个正则表达式:
“这是测试字符串\n{%set var=2%}\n{%verbatim%}\n内部
逐字记录1{%set var2=4%}\n{%endverbatim%}{%set value=10%}\n{%
verbatim%}在verbatim 2内{%set new_val=13%}\n{%endverbatim%}\n
……”
上述功能的输出:
'这是测试字符串\n{%set var=2%}{%verbatim%}\n
逐字记录1{%set var2=4%}\n{%endverbatim%}{%set value=10%}\n{%
verbatim%}在verbatim 2内{%set new_val=13%}\n{%endverbatim%}…' 我想要的结果是: '这是测试字符串\n{%set var=2%}{%verbatim%}\n 逐字记录1{%set var2=4%}\n{%endverbatim%}{%set value=10%}{% verbatim%}在verbatim 2内{%set new_val=13%}\n{%endverbatim%}\n …'
您可以将
re.sub
与回调一起使用:
str = "This is test string\n {% set var=2 %}\n {% verbatim %}\n Inside verbatim 1 {% set var2=4%}\n {% endverbatim %} {% set value=10%}\n {% verbatim%} Inside verbatim 2 {% set new_val=13%}\n {% endverbatim %}\n ..."
def replcb(m):
if m.group(1) == None:
return "%}"
else:
return m.group(1)
print re.sub(r'({%\s*verbatim\s*%}[\s\S]*?{%\s*endverbatim\s*%})+|%}\n', replcb, str)
- 此正则表达式捕获组#1中开始标记和结束标记之间的文本,否则
匹配而不捕获组%}\n
如果replcb
是有效捕获,则回调将原始捕获的字符串放回输出,否则m.group(1)
将替换为\n
%}
This is test string
{% set var=2 %} {% verbatim %}
Inside verbatim 1 {% set var2=4%}
{% endverbatim %} {% set value=10%} {% verbatim%} Inside verbatim 2 {% set new_val=13%}
{% endverbatim %}
...
您可以使用
import re
template_string = "This is test string\n {% set var=2 %}\n {% verbatim %}\n Inside verbatim 1 {% set var2=4%}\n {% endverbatim %} {% set value=10%}\n {% verbatim%} Inside verbatim 2 {% set new_val=13%}\n {% endverbatim %}\n ..."
x = re.sub(r"(?s)((?:{%\s*verbatim\s*%}.*?)?{%\s*endverbatim\s*%})|%}\n", lambda m: (m.group(1) if m.group(1) else "%}"), template_string)
print(x)
看
(?s)((?:{%\s*verbatim\s*%}.*?{%\s*endverbatim\s*%})|%}\n
正则表达式匹配:
-启用DOTALL模式((?s)
也匹配换行符)
-匹配的组1(((?:{%\s*verbatim\s*}.*?{%\s*endverbatim\s*})
-一次或零次出现(=可选匹配)(?:{%\s*verbatim\s*}.*?
后跟零个或多个空格,然后{%
,然后再次零个或多个空格,后跟verbatim
,然后零个或多个字符,但尽可能少,直到%}
-{%\s*endverbatim\s*%}
其中空格数可以是任意的{%endverbatim%}
-或|
-a%}\n
+换行符%}
在更换部件中,lamda用于检查组1是否已初始化(不是无),因为如果未初始化,则带有
\1
的更换模式将失败。阅读此问题。你可以使用lookaheads和lookbehindsCheck来实现这一点-它是否按预期工作?@WiktorStribiż新的感谢解决方案正在工作。我将发布解释。是的,当然。解决方案对其他人也有帮助。我想删除每个“%}”后面的换行符,除了{%verbatim%}{%endverbatim%}之间的内容,如:{%verbatim%}{%set var=10%}\n{%endverbatim%}。如果“%}\n”出现在{%verbatim%}{%endverbatim%}之间,则不会删除换行符
import re
template_string = "This is test string\n {% set var=2 %}\n {% verbatim %}\n Inside verbatim 1 {% set var2=4%}\n {% endverbatim %} {% set value=10%}\n {% verbatim%} Inside verbatim 2 {% set new_val=13%}\n {% endverbatim %}\n ..."
x = re.sub(r"(?s)((?:{%\s*verbatim\s*%}.*?)?{%\s*endverbatim\s*%})|%}\n", lambda m: (m.group(1) if m.group(1) else "%}"), template_string)
print(x)