在嵌套大括号内添加自己的文本

add own text inside nested braces

我有这个文本源,其中同时包含 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,但是我现在做不到,对我现在的水平来说太复杂了

有人可以解决吗?

Pyparsing 有一个名为 nestedExpr 的辅助方法,可以轻松匹配嵌套 open/close 分隔符的字符串。由于您在 <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']]

您只想匹配 那些起始文本为 'h1' 的标签。我们可以使用 addCondition:

向 pyparsing 中的表达式添加条件
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')
    )

最后,我们必须再添加一个解析时回调操作,以将 "MY_TEXT" 附加到标签:

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>

注意:这将在 每个 <h1> 标签后添加 "MY_TEXT"。如果您希望在包含 PHP 的 <h1> 标签之后 应用它,请编写适当的条件并将其添加到 nested_angle_braces_with_h1.