在双花括号之间:替换特定文本

时间:2015-08-16 19:55:45

标签: python regex django python-2.7

我有一个字符串(Python 2.7.3),它在Django中作为模板呈现,但我不认为这是Django特有的。该字符串来自docx文件中的document.xml文件。我正在使用文档xml渲染它并将其放回docx中以获取一些简单的邮件合并类型。

除了我可以使用的模板标签的明显限制之外,其中一个问题是,如果您在Word中编辑文本,Word会喜欢放入一大堆xml。

根据我的需要,如果可以,我会成功

  1. 在双花括号之间找到所有",并用引号"替换。
  2. 我想将"替换为",如下所示:

    word_docxml = 'some text here {{form.letterdate|date:"Y-m-d"}} and more text'
    

    我正在读这些:

    但无法将它放在一起。

    1. 如何删除/删除内部所有内容,并将< >置于{{ }}之间,如下所示:

      <w:rPr>
        <w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/>
        <w:color w:val="00000A"/>
        <w:sz w:val="22"/>
        <w:szCs w:val="22"/>
        <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
      </w:rPr>
      <w:t>{{form.</w:t>undefined</w:r>undefined<w:r>
      <w:rPr>
        <w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/>
        <w:b w:val="false"/>
        <w:bCs w:val="false"/>
        <w:color w:val="00000A"/>
        <w:sz w:val="22"/>
        <w:szCs w:val="22"/>
        <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
      </w:rPr>
      <w:t>L</w:t>undefined</w:r>undefined<w:r>
      <w:rPr>
        <w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/>
        <w:color w:val="00000A"/>
        <w:sz w:val="22"/>
        <w:szCs w:val="22"/>
        <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
      </w:rPr>
      <w:t>etterDate.value|date:"Y-m-d"}}</w:t>undefined</w:r>
      
    2. 会导致以下结果(道歉,我似乎无法突出感兴趣的领域):

      <w:rPr>
        <w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/>
        <w:color w:val="00000A"/>
        <w:sz w:val="22"/>
        <w:szCs w:val="22"/>
        <w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/>
      </w:rPr>
      <w:t>{{form.LetterDate.value|date:"Y-m-d"}}</w:t>undefined</w:r>
      

      如何处理这个?正则表达式是否可行;如果是这样,如何将命令放在一起?

      这不是Between double curly braces: replace particular text的重复,因为它没有提到为搜索范围处理开始和结束的双花括号(这是我的真正问题,我已阅读了许多示例,但无法获取格式正确的替换模式)。另一篇文章是关于在XHTML中解析html实体的子集;在我的帖子中没有需要,提及或质疑的XHTML解析。这篇文章在这里询问如何在两个其他已知的开始/结束模式之间移除和/或替换重复模式。我提供了一个简短的背景,从简单到复杂的两个具体例子,希望学习如何完成我当前的任务 - 我最好的希望是得到A部分的解释并将自己的方法应用到B部分。我得到了智能的讨论和超级回复来自社区的乐于助人的成员。我的帖子根本不涉及HTML,因为我在Django中呈现的模板被添加回docx存档并保存到文件存储中。它不是重复的(无论如何都是标记的副本)。

2 个答案:

答案 0 :(得分:1)

是的,正则表达式对此非常有用!

a)使用此:

 re.sub(r"(\{\{[^}]+}\})", lambda m: re.sub("&quot;", '"', m.group(1)), word_docxml)

结果:

>>> word_docxml = 'some text here {{form.letterdate|date:&quot;Y-m-d&quot;}} and &quot; more text'
>>> re.sub(r"(\{\{[^}]+}\})", lambda m: re.sub("&quot;", '"', m.group(1)), word_docxml)
'some text here {{form.letterdate|date:"Y-m-d"}} and &quot; more text'

b)更多相同,只是匹配大括号内的不同内容;

re.sub(r"(\{\{[^}]+}\})", lambda m: re.sub("<[^>]+>", "", m.group(1)), s)

结果:

>>> s = """<w:rPr><w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/><w:color w:val="00000A"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr><w:t>{{form.</w:t></w:r><w:r><w:rPr><w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/><e"/><w:bCs w:val="false"/><w:color w:val="00000A"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr><w:t>L</w:t></w<w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/><w:color w:val="00000A"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US"-US" w:bidi="ar-SA"/></w:rPr><w:t>etterDate.value|date:"Y-m-d"}}</w:t></w:r>"""
>>> re.sub(r"(\{\{[^}]+}\})", lambda m: re.sub("<[^>]+>", "", m.group(1)), s)
'<w:rPr><w:rFonts w:eastAsia="Times New Roman" w:cs="Arial" w:ascii="Arial" w:hAnsi="Arial"/><w:color w:val="00000A"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="en-US" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr><w:t>{{form.LetterDate.value|date:"Y-m-d"}}</w:t></w:r>'

说明,因为您要求提供指导,而不仅仅是答案;

re.sub(r"(\{\{[^}]+}\})", lambda m: re.sub("&quot;", '"', m.group(1)), word_docxml)

这种方法的工作方式是首先匹配双支撑间隔。 lambda表达式只接受在该匹配中找到的组,并替换相关内容。

较小的正则表达式解释说:

&quot;     # Just matching that, nothing fancy

匹配标签的模式;

<     # Opening of tag
[^>]+ # Followed by 1 or more characters that are not closing tags
>     # Followed by a closing tag

答案 1 :(得分:0)

在测试正则表达式时,必须要小心它不匹配太多(误报)。鉴于您的复杂输入,这变得更加重要。

例如,正则表达式不匹配

&quot;

以下

test { &quot; }}text
test  &quot; }}

关于你的第二个问题,我会在2遍中做到这一点,以保持正则表达式很简单

首先使用此正则表达式匹配{{和}}

之间的内容
\{\{(.*?)\}\}

现在仅将功能应用于组1的内容。 我熟悉.NET,允许这样做,我希望你的语言也是如此

要应用的功能再次是一个没有任何内容的替代正则表达式

<[^>]*>

我希望我的Python方言正确。

第一个问题可以使用相同的想法。