在python中扩展string.Template类以便于正则表达式

时间:2011-08-31 20:11:27

标签: python regex

我非常喜欢python的一切,这要归功于它的简单性。我觉得正则表达式让我远离了对蟒蛇的热爱。因此我想扩展已经存在的string.Template类,它允许我在字符串中设置变量,以便我可以获得已存在的字符串的值。

我的第一次尝试效果很好但有一些缺点:

import re
from string import Template
class TemplateX(Template):
    def getvalues(self,Str):
        regex = r""
        skipnext = False
        for i in self.template:
            if skipnext == False:
                if i != "$":
                    regex += i
                else:
                    regex += r"(.+)"
                    skipnext = True
            else:
                skipnext = False
        values = re.search(regex,Str).groups()
        return values

temp = TemplateX("  Coords;     $x;$y;$z;\n")
newstring = temp.substitute(x="1",y="2",z="3")
print newstring

values = temp.getvalues(newstring)
print values

newstring打印为:“Coords; 1; 2; 3; \ n”

值打印为:(“1”,“2”,“3”)

我很好,因为这种简单的方法失去了一些re的功能。 我的问题是如何为getvalues添加更多功能,以允许TemplateX中的变量超过1个字符(如Template类和替换允许)。即使这样有效:

temp = TemplateX("  Coords;     $xvar;$yvar;$zvar;\n")
newstring = temp.substitute(xvar="1",yvar="2",zvar="3")
print newstring

values = temp.getvalues(newstring)
print values

temp2 = TemplateX("  FindThese:    $gx = $gy - $gz")
values2 = temp2.getvalues("  FindThese:    $10000 = $10 - $5x")

2 个答案:

答案 0 :(得分:3)

你几乎想把模板变成正则表达式读取那个模板,对吧?这并不总是可行,例如,如果您有模板"$x$y"和字符串"abc",则无法知道它是("ab", "c")("abc", "")还是其他一些情况。并且不仅仅是模板变量彼此相邻的情况。

因此,如果你想要这种东西,你必须知道你提供给它的字符串中有什么。也就是说 - 变量之间没有出现变量本身的变量(即变量都是数字,模板中有分号)。如果您只是解析一些输入,那么如果您只编写自己的正则表达式,则可能会更安全。

那就是说,你可以做这样的事情:

class TemplateX(Template):
    def getvalues(self,Str):
        """ Reads a string matching the template to find the original values.

            >>> temp = TemplateX("Blah: $xx;$y;")
            >>> newsting = temp.substitute(xx="1",y="2")
            >>> temp.getvalues(newstring)
            ('1', '2')

        """
        regex = re.sub(self.pattern, "(.*)", self.template)
        m = re.match(regex, Str)
        return m.groups()

它使用Template自己的机制来查找占位符并用正则表达式通配符替换它们。然后它在给定的字符串上运行正则表达式。

您还可以尝试获取初始关键字参数:

    def getvalues(self,Str):
        regex = re.sub(self.pattern, r"(?P<\2>.*)", self.template)
        m = re.match(regex, Str)
        return m.groupdict()

然后用:

来阻止它
temp = TemplateX("$a$a")
newstring = temp.substitute(a='a')
print temp.getvalues(newstring)

答案 1 :(得分:0)