【问题标题】:How to replace text in repeated fragments inside parent text using re module?如何使用 re 模块替换父文本中重复片段中的文本?
【发布时间】:2021-02-05 22:42:25
【问题描述】:

我有一个 html 文件,其中包含重复的 code 标签:


<h3>Post header content</h3>

<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum, delectus.
</p>

<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam culpa illo necessitatibus 
    officia sed totam. Aspernatur cupiditate debitis eos obcaecati! Dolores eveniet excepturi hic optio.
</p>

<code class="code">
$ pip install --no-cache-dir -r requirements.txt

</code>


<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
    Accusamus et hic neque, suscipit totam ullam.</p>


<code class="code">

// Linux
export FLASK_APP=app.py
export FLASK_ENV=development

// Windows
set FLASK_APP=app.py
set FLASK_ENV=development

</code>

<p>More text...</p>


我想找到所有 code 标签,用它们做一些刺痛操作并返回到源字符串。 这是我的代码片段:

import re

def code2replace(code):
    # find all code fragments
    RE_CODE = r'<code[^>]+>(.*?)<\/code>'
    matches = re.finditer(RE_CODE, code, re.S)
    

    rs_text = ''
    code_text = ''
    pos_start = 0

    for match in matches:
        # print(f'Start: {match.start()}, End: {match.end()}, Content: {match.group(1)}')
        code_text = match.group(1).replace('\n', '\n<br/>')

        rs_text += code[pos_start: match.start()] + f'<code class="code">{code_text}</code>'
        pos_start = match.end()

    return rs_text


但不幸的是,这不能正常工作。

那么,如何改变这个html中code标签的内容并返回改变的结果呢?

【问题讨论】:

  • 您是否考虑过使用合适的 HTML 解析器?
  • FWIW 我同意@tobias_k,使用正则表达式解析 HTML 通常被认为是一种糟糕的编程习惯。

标签: python replace python-re


【解决方案1】:

您的代码似乎确实有效,但可以通过使用re.sub 而不是re.finditer 大大简化它,因此您不必将各个匹配项的开始和结束位置的全文拼凑在一起:

def code2replace(html):
    def fix_code(match):
        code = match.group(1).replace("\n", "\n<br>")
        return f'<code class="code">{code}</code>'
    RE_CODE = r'<code[^>]+>(.*?)<\/code>'
    return re.sub(RE_CODE, fix_code, html, flags=re.S)

所有这些也可以用lambda 在一行中完成,但我认为这种方式更具可读性和可扩展性。就像您的代码一样,这将替换例如第一个代码块:

<code class="code">
<br>$ pip install --no-cache-dir -r requirements.txt
<br>
<br></code>

请注意,这还将用相同的&lt;code&gt; 标记替换任何打开的&lt;code&gt; 标记,忽略任何其他属性或不同的class 值。要保留原来的&lt;code> 标签,你可以只使用return match.group().replace("\n", "\n&lt;br&gt;")group(),而不是group(1))。

【讨论】:

    【解决方案2】:

    它正在工作。在输出中注释(用于调试)。

    0: regex finds this block at first and updates \n with \n<br/>
    <br/>$ pip install --no-cache-dir -r requirements.txt
    <br/>
    <br/>
    1: then regex finds this block and updates \n with \n<br/>
    <br/>
    <br/>// Linux
    <br/>export FLASK_APP=app.py
    <br/>export FLASK_ENV=development
    <br/>
    <br/>// Windows
    <br/>set FLASK_APP=app.py
    <br/>set FLASK_ENV=development
    <br/>
    <br/>
    

    完整输出:

    <h3>Post header content</h3>
    
    <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cum, delectus.
    </p>
    
    <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam culpa illo necessitatibus
        officia sed totam. Aspernatur cupiditate debitis eos obcaecati! Dolores eveniet excepturi hic optio.
    </p>
    
    <code class="code">
    <br/>$ pip install --no-cache-dir -r requirements.txt
    <br/>
    <br/></code>
    
    
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Accusamus et hic neque, suscipit totam ullam.</p>
    
    
    <code class="code">
    <br/>
    <br/>// Linux
    <br/>export FLASK_APP=app.py
    <br/>export FLASK_ENV=development
    <br/>
    <br/>// Windows
    <br/>set FLASK_APP=app.py
    <br/>set FLASK_ENV=development
    <br/>
    <br/></code>
    

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 1970-01-01
      • 2018-07-01
      • 2020-05-01
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      相关资源
      最近更新 更多