3

是否可以用键作为正则表达式和操作(带参数)作为值来实现字典?

例如

  1. key = "actionname 1 2", value = "method(1, 2)"
  2. key = "differentaction par1 par2", value = "appropriate_method(par1, par2)"

用户键入密钥,我需要使用作为用户输入的一部分提供的参数执行匹配方法。

如果我们能够及时实现查找,那就太好了O(1),即使它至少不可能,我正在寻找解决这个问题的解决方案。

我将有几百个正则表达式(比如300)和匹配的参数化操作来执行。

我可以编写一个循环来实现这一点,但是有没有什么优雅的方法可以在不使用 for 循环的情况下做到这一点?

相关问题:Hashtable/dictionary/map lookup with regular expressions

4

4 回答 4

7

是的,完全有可能:

import re
dict = {}
dict[re.compile('actionname (\d+) (\d+)')] = method
dict[re.compile('differentaction (\w+) (\w+)')] = appropriate_method

def execute_method_for(str):
    #Match each regex on the string
    matches = (
        (regex.match(str), f) for regex, f in dict.iteritems()
    )

    #Filter out empty matches, and extract groups
    matches = (
        (match.groups(), f) for match, f in matches if match is not None
    )


    #Apply all the functions
    for args, f in matches:
        f(*args)
于 2012-06-07T11:49:24.147 回答
4

当然,你的字典的值可以是 python 函数。

您的匹配函数可以尝试将您的字符串与每个键匹配,并在匹配时执行适当的函数。在最好的情况下,这将是线性的,但我认为如果你想使用正则表达式,你会得到更好的结果。

但是查看您的示例数据,我认为您应该重新考虑是否需要正则表达式。也许您可以将输入字符串解析为例如<procedure-name> <parameter>+,然后通过其名称(简单字符串)查找适当的过程,这可以是O(1)

于 2012-06-07T11:42:52.817 回答
2

不幸的是,这是不可能的。您将需要遍历正则表达式以找出它们是否匹配。字典中的查找将是O(1)(但这并不能解决您的问题)。

于 2012-06-07T11:44:35.277 回答
1

恕我直言,您问的是错误的问题

  1. 你问是否有一种优雅的方式来做到这一点。答: 最优雅的方式是最明显的方式。 代码被修改的频率将增加 10 到 20 倍。因此,如果你写了一些难以阅读和快速理解的“优雅”的东西,你只是破坏了你之后必须以某种方式修改它的人。

  2. 更好的代码:

这里的另一个答案是这样的:

matches = ( (regex.match(str), f) for regex, f in dict.iteritems() )

这在功能上等效(重要的是,在 Python 生成的字节码方面相同):

# IMHO 'regex' var should probably be named 'pattern' since it's type is <sre.SRE_Pattern>

for pattern, func in dictname.items():
    if pattern.match(str):
        func()

但是,下面的示例更容易一目了然地阅读和理解

I apologize (a little) if you're one of those people who is offended by code that is even slightly more wordy than you think it could be. My criteria, and Guido's as mentioned in PEP-8, is that the clearest code is the best code.

于 2013-06-06T21:13:06.293 回答