如何评估 html 字符串中的 Python 代码?

How can Python code within html string be evaluated?

我正在尝试创建一个 HTML 文件,其中确定了 Python 必须评估的变量。我的代码如下所示:

name = ['Nora', 'John', 'Jack', 'Jessica']

html = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Names</title>
</head>
<body>
    <ul>
        <li>Mother: <%= name[0] %></li>
        <li>Father: <%= name[1] %></li>
        <li>Son: <%= name[2] %></li>
        <li>Daughter: <%= name[3] %></li>
    </ul>
</body>
</html>
"""

Html_file = open("names.html","w")
Html_file.write(html)
Html_file.close()

但是,数组在输出期间不被解释。我的 HTML 来源如下所示:

...
<ul>
    <li>Mother: <%= name[0] %></li>
    <li>Father: <%= name[1] %></li>
    <li>Son: <%= name[2] %></li>
    <li>Daughter: <%= name[3] %></li>
</ul>
...

如何计算被 <%= %> 包围的 python 代码?

    html = """<ul>
        <li>Mother:  {0} </li>
        <li>Father:  {1} </li>
        <li>Son: {2} </li>
        <li>Daughter: {3} </li>
        </ul>"""
    name = ['Nora', 'John', 'Jack', 'Jessica']
    print(html.format(*name))
    >>><ul>
        <li>Mother: Nora </li>
        <li>Father: John </li>
        <li>Son: Jack </li>
        <li>Daughter: Jessica </li>
       </ul>

字符串不会自动计算内部代码,但您可以通过多种方式实现:

引入占位符并格式化您的字符串:

name = ['Nora', 'John', 'Jack', 'Jessica']

html = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Names</title>
</head>
<body>
    <ul>
        <li>Mother: {0}</li>
        <li>Father: {1}</li>
        <li>Son: {2}</li>
        <li>Daughter: {3}</li>
    </ul>
</body>
</html>
"""

Html_file = open("names.html","w")
Html_file.write(html.format(name[0], name[1], name[2], name[3])
Html_file.close()

这是一种非常简单的方法。还有更高级的方法,例如使用模板引擎。 Here 您可以阅读更多关于它们的信息。

有多种实现方法

首先,如果您使用的是 Python 3.6 或更高版本,则有一个名为 的新语法,它基本上是字符串的一种方法在 运行 时间格式化。

name = ['Nora', 'John', 'Jack', 'Jessica']

html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Names</title>
</head>
<body>
    <ul>
        <li>Mother: {name[0]}</li>
        <li>Father: {name[1]}</li>
        <li>Son: {name[2]}</li>
        <li>Daughter: {name[3]}</li>
    </ul>
</body>
</html>
"""

print(html)

使用f-string的方法很简单,在字符串的开头添加一个f,然后使用{ }代替<%= %>


如果您正在使用 任何 Python 版本,或者想要 version-compatible 方法,还有许多其他方法 string interpolation (即 C-style 字符串格式 %、Python 字符串格式 .format() 和字符串连接),其中一个 (.format()) 在其他答案中。


不改变你的 HTML:使用 reeval

如果您无法控制获得 "need-to-be-substituted" html 的位置,或者如果您 必须 使用 <%= %>方案,您可以简单地使用 reeval:

的组合
from re import sub


name = ['Nora', 'John', 'Jack', 'Jessica']

html = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Names</title>
</head>
<body>
    <ul>
        <li>Mother: <%= name[0] %></li>
        <li>Father: <%= name[1] %></li>
        <li>Son: <%= name[2] %></li>
        <li>Daughter: <%= name[3] %></li>
    </ul>
</body>
</html>
"""

html = sub(r"<%=\s*(\S+)\s*%>", lambda l: eval(l.group(1)), html)

print(html)

您可以使用正则表达式来更准确地评估模板:

import re
name = ['Nora', 'John', 'Jack', 'Jessica']
def render_template(html, **kwargs):
  return re.sub('\<%\=\s[a-zA-Z]+\[\d+\]\s%\>', '{}', html).format(*[kwargs.get(re.findall('[a-zA-Z]+', i)[0])[int(re.findall('\d+', i)[0])] for i in re.findall('(?<=\<%\=\s)[a-zA-Z]+\[\d+\](?=\s%)', html)])

print(render_template(html, name = name))

输出:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Names</title>
</head>
<body>
<ul>
    <li>Mother: Nora</li>
    <li>Father: John</li>
    <li>Son: Jack</li>
    <li>Daughter: Jessica</li>
  </ul>
</body>
</html>

如果以随机顺序访问 name 个元素,此解决方案也适用:

html = """
<body>
  <ul>
    <li>Mother: <%= name[3] %></li>
    <li>Father: <%= name[1] %></li>
    <li>Son: <%= name[0] %></li>
    <li>Daughter: <%= name[2] %></li>
 </ul>
</body>
"""
print(render_template(html, name = name))

输出:

<body>
  <ul>
   <li>Mother: Jessica</li>
   <li>Father: John</li>
   <li>Son: Nora</li>
   <li>Daughter: Jack</li>
</ul>
</body>