Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python正则表达式:我想删除每个';%}之后的换行符';标记关闭,{%verbatim%}之间的内容除外。。。{%endverbatim%}标记_Python_Regex_String_Algorithm - Fatal编程技术网

Python正则表达式:我想删除每个';%}之后的换行符';标记关闭,{%verbatim%}之间的内容除外。。。{%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("{%

我正在编写正则表达式,用于在每个标记结束后删除换行符,如模板字符串的“%}\n”。但是,当内容位于{%verbatim%}content{%endverbatim%}标记之间时,它不应该删除,并且如果存在{%endverbatim%}之后的换行符,它也不应该删除

我试过这个:

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
正则表达式匹配:

  • (?s)
    -启用DOTALL模式(
    也匹配换行符)
  • (((?:{%\s*verbatim\s*}.*?{%\s*endverbatim\s*})
    -匹配的组1
    • (?:{%\s*verbatim\s*}.*?
      -一次或零次出现(=可选匹配)
      {%
      后跟零个或多个空格,然后
      verbatim
      ,然后再次零个或多个空格,后跟
      %}
      ,然后零个或多个字符,但尽可能少,直到
    • {%\s*endverbatim\s*%}
      -
      {%endverbatim%}
      其中空格数可以是任意的
  • |
    -或
  • %}\n
    -a
    %}
    +换行符

在更换部件中,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)