如何评估 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:使用 re
和 eval
如果您无法控制获得 "need-to-be-substituted" html 的位置,或者如果您 必须 使用 <%= %>
方案,您可以简单地使用 re
和 eval
:
的组合
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>
我正在尝试创建一个 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:使用 re
和 eval
如果您无法控制获得 "need-to-be-substituted" html 的位置,或者如果您 必须 使用 <%= %>
方案,您可以简单地使用 re
和 eval
:
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>