【问题标题】:Replacing html script element sources with regular expression in Python在 Python 中用正则表达式替换 html 脚本元素源
【发布时间】:2013-02-20 15:02:49
【问题描述】:

我正在尝试编写一个大型 python/bash 脚本,将我的 html/css 模型转换为 Shopify 主题。 此过程中的一个步骤是更改所有脚本源。例如:

<script type="text/javascript" src="./js/jquery.bxslider.min.js"></script>

变成

<script type="text/javascript" src="{{ 'jquery.bxslider.min.js' | asset_url }}"></script>

这是我目前所拥有的:

import re
test = """
  <script type="text/javascript" src="./js/jquery-1.8.3.min.js"></script>
  <!--<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>-->
  <script type="text/javascript" src="./js/ie-amendments.js"></script>
  <script type="text/javascript" src="./js/jquery.bxslider.min.js"></script>
  <script type="text/javascript" src="./js/jquery.colorbox-min.js"></script>
  <script type="text/javascript" src="./js/main.js"></script>
"""
out = re.sub( 'src=\"(.+)\"', 'src="{{ \'\\1\' | asset_url }}"', test, flags=re.MULTILINE )
out

打印出来

'\n  <script type="text/javascript" src="{{ \'./js/jquery-1.8.3.min.js\' | asset_url }}"></script>\n  <!--<script src="{{ \'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript\' | asset_url }}"></script>-->\n  <script type="text/javascript" src="{{ \'./js/ie-amendments.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/jquery.bxslider.min.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/jquery.colorbox-min.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/main.js\' | asset_url }}"></script>\n'

到目前为止我有两个问题:

  1. 我用来转义单字的一些反斜杠字符 我的正则表达式中的引号显示在输出中。

  2. 我的捕获组正在捕获整个原始源字符串,但是 我只需要最后一个“/”之后的内容

回答: 根据 Martijn Pieters 的有用建议,我查看了 ?正则表达式运算符,并提出了这个解决方案,完美地解决了我的问题。此外,对于替换表达式,我将其封装在双引号中,而不是单引号,并转义双引号,最终删除了不必要的反斜杠。谢谢大家!

re.sub( r'src=".+?([^/]+?\.js)"', "src=\"{{ '\\1' | asset_url }}\"", test, flags=re.MULTILINE )

【问题讨论】:

  • @Cfreak:这可能是一个足够有限的案例; script 标签不包含其他标签,src 属性匹配受到限制且足够规则。没必要在这里下意识的。
  • @Cfreak:实际上不知道正则表达式不利于解析 HTML。感谢您的链接 - 它提供了非常丰富的信息!
  • 没问题。在 Python 中,用于解析 HTML 的一个非常好的模块是 BeautifulSoup crummy.com/software/BeautifulSoup
  • 不要使用正则表达式解析 HTML。您无法使用正则表达式可靠地解析 HTML。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。有关如何使用 Python 模块正确解析 HTML 的示例,请参阅 htmlparsing.com/python.html

标签: python regex escaping html-parsing shopify


【解决方案1】:

你的表达效果很好; Python 只是向您展示了一个 字符串文字,您必须在其中转义引号才能将其重新用作 Python 字符串。

如果您打印该值,则不会发生此类转义:

>>> re.sub( 'src=\"(.+)\"', 'src="{{ \'\\1\' | asset_url }}"', test, flags=re.MULTILINE )
'\n  <script type="text/javascript" src="{{ \'./js/jquery-1.8.3.min.js\' | asset_url }}"></script>\n  <!--<script src="{{ \'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript\' | asset_url }}"></script>-->\n  <script type="text/javascript" src="{{ \'./js/ie-amendments.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/jquery.bxslider.min.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/jquery.colorbox-min.js\' | asset_url }}"></script>\n  <script type="text/javascript" src="{{ \'./js/main.js\' | asset_url }}"></script>\n'
>>> print(re.sub( 'src=\"(.+)\"', 'src="{{ \'\\1\' | asset_url }}"', test, flags=re.MULTILINE ))

  <script type="text/javascript" src="{{ './js/jquery-1.8.3.min.js' | asset_url }}"></script>
  <!--<script src="{{ 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript' | asset_url }}"></script>-->
  <script type="text/javascript" src="{{ './js/ie-amendments.js' | asset_url }}"></script>
  <script type="text/javascript" src="{{ './js/jquery.bxslider.min.js' | asset_url }}"></script>
  <script type="text/javascript" src="{{ './js/jquery.colorbox-min.js' | asset_url }}"></script>
  <script type="text/javascript" src="{{ './js/main.js' | asset_url }}"></script>

您可以使用? 来制作+*? 限定符非贪婪;匹配最小值而不是最大值。您还可以匹配任何 不是 引号的内容:

r'src="([^"]+)"'

更好地约束正则表达式的那一部分; [^"] 匹配任何双引号的字符。

在指定正则表达式模式时,通常最好使用 python 原始字符串文字 (r'') 代替,这样可以省去很多关于哪些需要转义和哪些不需要转义的麻烦。使用原始字符串文字,您的替换模式可以简化为:

r'src="{{ \'\1\' | asset_url }}"' 

最后一行:

re.sub(r'src="([^"]+)"', r'src="{{ \'\1\' | asset_url }}"', test, flags=re.MULTILINE)

【讨论】:

    【解决方案2】:

    在不引起某些人的愤怒的情况下,您可以将其视为 xml。

    txt = """<html>
    <script type="text/javascript" src="./js/jquery.bxslider.min.js"></script>
    <script type="text/javascript" src="./js/jquery.another.min.js"></script>
    </html>
    """
    
    import xml.etree.ElementTree as ET
    import os
    root = ET.fromstring(txt)
    
    for e in root.findall('script'):
        e.attrib['src'] =  "{{ '%s' | assert_url }}" % os.path.basename(e.attrib['src'])
    
    print ET.tostring(root)
    

    给予:

    <html>
    <script src="{{ 'jquery.bxslider.min.js' | assert_url }}" type="text/javascript" />
    <script src="{{ 'jquery.another.min.js' | assert_url }}" type="text/javascript" />
    </html>
    

    xml 文档之后可能会有用;这一切都取决于您的 HTML 格式有多好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 2016-05-23
      • 2014-10-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      相关资源
      最近更新 更多