在嵌套大括号中添加自己的文本+异常

时间:2017-08-24 01:17:46

标签: python-3.x pyparsing

原始问题位于here,当前的问题是希望避免一个问题。

我有这个代码,它与html_1数据完美配合:

from pyparsing import nestedExpr, originalTextFor

html_1 = '''
<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
    <body>
        <h1 <?php echo "class='big'" ?>>foo</h1>
    </body>
</html>
'''

html_2 = '''
<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
    <body>
        <h1 <?php echo $tpl->showStyle(); ?>>foo</h1>
    </body>
</html>
'''

nested_angle_braces = nestedExpr('<', '>')

# for match in nested_angle_braces.searchString(html):
#     print(match)

# nested_angle_braces_with_h1 = nested_angle_braces().addCondition(
#                                             lambda tokens: tokens[0][0].lower() == 'h1')

nested_angle_braces_with_h1 = originalTextFor(
    nested_angle_braces().addCondition(lambda tokens: tokens[0][0].lower() == 'h1')
    )
nested_angle_braces_with_h1.addParseAction(lambda tokens: tokens[0] + 'MY_TEXT')

print(nested_angle_braces_with_h1.transformString(html_1))

html_1变量的结果是:

<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
    <body>
        <h1 <?php echo "class='big'" ?>>MY_TEXTfoo</h1>
    </body>
</html>

这没关系,全部按预期放置。 MY_TEXT位于右侧区域(h1标签内)。

但是让我们看看html_2的结果:

<html>
<head>
<title><?php echo "title here"; ?></title>
<head>
    <body>
        <h1 <?php echo $tpl->showStyle(); ?>MY_TEXT>foo</h1>
    </body>
</html>

现在我们收到错误,MY_TEXT放在h1属性区域内,因为PHP在“$ tpl-&gt;”中包含了大括号。

我该如何解决?我需要在该地区获得此结果:

<h1 <?php echo $tpl->showStyle(); ?>>MY_TEXTfoo</h1>

1 个答案:

答案 0 :(得分:1)

解决方案要求我们为PHP标记定义一个特殊的表达式,我们的简单nestedExpr会被它混淆。

# define an expression for a PHP tag
php_tag = Literal('<?') + 'php' + SkipTo('?>', include=True)

我们现在需要的不仅仅是简单的字符串用于开启者和更接近的,包括在匹配&#39;&lt;&#39;确保我们不在PHP标签的前沿:

# define expressions for opener and closer, such that  we don't 
# accidentally interpret a PHP tag as a nested  expr
opener = ~php_tag + Literal("<")
closer = Literal(">")

如果开放者和更接近的人不是简单的字符串,那么我们也需要提供内容表达式。我们的内容定义非常简单,只需PHP标签或其他字样的印刷品,不包括&#39;&lt;&#39;和&#39;&gt;&#39; (无论如何,你最终会将这一切全部包裹起来):

originalTextFor

现在,如果我使用# define nested_angle_braces to potentially contain PHP tag, or # some other printable (not including '<' or '>' chars) nested_angle_braces = nestedExpr(opener, closer, content=php_tag | Word(printables, excludeChars="<>")) 来扫描nested_angle_braces.searchString,我会得到:

html_2