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

时间:2016-10-16 02:43:54

标签: python pyparsing python-textprocessing

我有这个包含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,但我现在无法得到它,对于我当前的级别来说太复杂了

有人可以提出解决方案吗?

1 个答案:

答案 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

为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')
    )

最后,我们还要添加一个解析时回调动作,以附加&#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