我在一个效率低下的mann中使用Python正则表达式

2024-10-01 07:41:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是创建一个非常简单的模板语言。目前,我正在用一个值替换一个变量,如下所示:

此输入:

The Web

应产生以下输出:

The Web This Is A Test Variable

我已经成功了。但是看看我的代码,我在同一个字符串上运行多个相同的正则表达式——这违反了我的效率感。一定有更好的,更像Python的方式。(这两个“while”循环才是真正的冒犯。)

这确实通过了单元测试,所以如果这是愚蠢的过早优化,告诉我——我愿意让它过去。一个文档中可能有几十个这样的变量定义和用法,但不是数百个。但我怀疑有明显的(对其他人来说)改进的方法,我很好奇StackOverflow的人群会想出什么样的方法。在

def stripMatchedQuotes(item):
    MatchedSingleQuotes = re.compile(r"'(.*)'", re.LOCALE)
    MatchedDoubleQuotes = re.compile(r'"(.*)"', re.LOCALE)
    item = MatchedSingleQuotes.sub(r'\1', item, 1)
    item = MatchedDoubleQuotes.sub(r'\1', item, 1)
    return item




def processVariables(item):
    VariableDefinition = re.compile(r'<%(.*?)=(.*?)%>', re.LOCALE)
    VariableUse = re.compile(r'<%(.*?)%>', re.LOCALE)
    Variables={}

    while VariableDefinition.search(item):
        VarName, VarDef = VariableDefinition.search(item).groups()
        VarName = stripMatchedQuotes(VarName).upper().strip()
        VarDef = stripMatchedQuotes(VarDef.strip())
        Variables[VarName] = VarDef
        item = VariableDefinition.sub('', item, 1)

    while VariableUse.search(item):
        VarName = stripMatchedQuotes(VariableUse.search(item).group(1).upper()).strip()
        item = VariableUse.sub(Variables[VarName], item, 1)

    return item

Tags: therewebsearchvariablesitemlocalestrip
3条回答

永远不要创建自己的编程语言。永远。(我以前对这个规则有一个例外,但现在不是了。)

总有一种现有的语言可以更好地满足你的需要。如果你详细描述了你的用例,人们可能会帮助你选择一种合适的语言。在

第一件可以改善的事情是重新编译功能之外。编译被缓存,但在检查它是否已编译时会出现速度问题。在

另一种可能是使用单个regex,如下所示:

MatchedQuotes = re.compile(r"(['\"])(.*)\1", re.LOCALE)
item = MatchedQuotes.sub(r'\2', item, 1)

最后,您可以在processVariables中将其组合到regex中。接受Torsten Marek's建议为使用函数re.sub公司,这大大改善和简化了事情。在

^{pr2}$

以下是我10万次跑步的时间安排:

Original       : 13.637
Global regexes : 12.771
Single regex   :  9.095
Final version  :  1.846

[编辑]添加缺少的非贪婪说明符

[Edit2]Added.upper()调用与原始版本一样不区分大小写

^{}可以将callable作为参数,而不是简单的字符串。使用它,您可以用一个函数调用替换所有变量:

>>> import re
>>> var_matcher = re.compile(r'<%(.*?)%>', re.LOCALE)
>>> string = '<%"TITLE"%> <%"SHMITLE"%>'
>>> values = {'"TITLE"': "I am a title.", '"SHMITLE"': "And I am a shmitle."}
>>> var_matcher.sub(lambda m: vars[m.group(1)], string)
'I am a title. And I am a shmitle.

跟随eduffy.myopenid.com网站的建议,并保留已编译的正则表达式。在

同样的方法也可以应用于第一个循环,只是在那里你需要先存储变量的值,并始终返回""作为替换。在

相关问题 更多 >