我有这个包含HTML标签和PHP代码的文本源:
<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
<body>
<h1 <?php echo "class='big'" ?>>foo</h1>
</body>
</html>
我需要在打开标签后放置我自己的文本(例如:MY_TEXT)并获得此结果:
<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
<body>
<h1 <?php echo "class='big'" ?>>MY_TEXTfoo</h1>
</body>
</html>
因此我需要考虑嵌套大括号
如果我将使用正则表达式,它将产生问题(我需要考虑任何级别的嵌套大括号)。我需要另一种策略。
现在我的想法尝试使用pyparsing,但我现在无法得到它,对于我当前的级别来说太复杂了
有人可以提出解决方案吗?
答案 0 :(得分:1)
Pyparsing有一个名为nestedExpr
的辅助方法,可以很容易地匹配嵌套的打开/关闭分隔符的字符串。由于您在<h1>
标记中嵌套了PHP标记,因此我会使用nestedExpr
之类的:
nested_angle_braces = nestedExpr('<', '>')
但是,这将匹配输入HTML源中的每个标记:
for match in nested_angle_braces.searchString(html):
print match
给出:
[['html']]
[['head']]
[['title']]
[['?php', 'echo', '"title here"', ';', '?']]
[['/title']]
[['head']]
[['body']]
[['h1', ['?php', 'echo', '"class=\'big\'"', '?']]]
[['/h1']]
[['/body']]
[['/html']]
您希望仅匹配 那些开头文字为&#39; h1&#39;的标记。我们可以使用addCondition
:
nested_angle_braces_with_h1 = nested_angle_braces().addCondition(
lambda tokens: tokens[0][0].lower() == 'h1')
现在我们只匹配所需的标签。再多做几步......
首先,nestedExpr
返回匹配项的嵌套列表。我们想要匹配的原始文本。 Pyparsing包含另一个帮助器,缺乏想象力的originalTextFor
- 我们将它与之前的定义结合起来得到:
nested_angle_braces_with_h1 = originalTextFor(
nested_angle_braces().addCondition(lambda tokens: tokens[0][0].lower() == 'h1')
)
最后,我们还要添加一个解析时回调动作,以附加&#34; MY_TEXT&#34;到标签:
nested_angle_braces_with_h1.addParseAction(lambda tokens: tokens[0] + 'MY_TEXT')
现在我们可以匹配所需的<h1>
代码,我们可以使用表达式的transformString
方法为我们执行搜索和替换工作:
print(nested_angle_braces_with_h1.transformString(html))
将原始样本保存为名为html
的变量,我们得到:
<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
<body>
<h1 <?php echo "class='big'" ?>>MY_TEXTfoo</h1>
</body>
</html>
注意:这将添加&#34; MY_TEXT&#34;在每个 <h1>
标记之后。如果您希望在包含PHP的<h1>
标记之后仅应用此项,请编写适当的条件并将其添加到nested_angle_braces_with_h1
。