首页 文章

python中已编译的正则表达式对象的类型

提问于
浏览
55

python中编译的正则表达式的类型是什么?

特别是,我想评估

isinstance(re.compile(''), ???)

为了内省目的,这是真的 .

我有一个解决方案,有一些全局常量 REGEX_TYPE = type(re.compile('')) ,但它看起来并不优雅 .

EDIT: 我想这样做的原因是因为我有字符串列表和编译的正则表达式对象 . 我想"match"反对列表的字符串,by

  • 对于列表中的每个字符串,尝试检查字符串是否相等 .

  • 对于列表中的每个正则表达式,尝试检查字符串是否与给定模式匹配 .

我想出的代码是:

for allowed in alloweds:
    if isinstance(allowed, basestring) and allowed == input:
        ignored = False
        break
    elif isinstance(allowed, REGEX_TYPE) and allowed.match(input):
        ignored = False
        break

9 回答

  • 28

    Disclaimer: 这不是针对您的特定需求的直接答案,而是作为替代方法可能有用的东西


    您可以保持duck typing的理想,并使用 hasattr 来确定对象是否具有您要使用的某些属性 . 例如,您可以执行以下操作:

    if hasattr(possibly_a_re_object, "match"): # Treat it like it's an re object
        possibly_a_re_object.match(thing_to_match_against)
    else:
        # alternative handler
    
  • 3

    当某些东西的类型没有't well specified, there'使用 type builtin在运行时发现答案没有错:

    >>> import re
    >>> retype = type(re.compile('hello, world'))
    >>> isinstance(re.compile('goodbye'), retype)
    True
    >>> isinstance(12, retype)
    False
    >>>
    

    在运行时发现类型可以保护您不必访问私有属性以及将来对返回类型的更改 . 在这里使用 type 并没有什么不优雅,尽管可能有一些不太优雅的想要知道这种类型 .

  • 14

    Python 3.5引入了typing模块 . 其中包括typing.re.Pattern_TypeAlias .

    从Python 3.6开始,您可以简单地执行以下操作:

    from typing.re import Pattern
    
    my_re = re.compile('foo')
    assert isinstance(my_re, Pattern)
    

    在3.5中,曾经有一个bug要求你这样做:

    assert issubclass(type(my_re), Pattern)
    

    根据文档和测试套件,不保证可以使用 .

  • 19

    可以将编译的正则表达式与're._pattern_type'进行比较

    import re
    pattern = r'aa'
    compiled_re = re.compile(pattern)
    print isinstance(compiled_re, re._pattern_type)
    
    >>True
    

    至少在版本2.7中给予真实

  • 26

    预防胜于治疗 . 首先不要创建这样的异构列表 . 拥有 set 允许的字符串和已编译的正则表达式对象列表 . 这应该使您的检查代码看起来更好并且运行得更快:

    if input in allowed_strings:
        ignored = False
    else:
        for allowed in allowed_regexed_objects:
            if allowed.match(input):
                ignored = False
                break
    

    如果您无法避免创建此类列表,请查看是否有机会检查它并构建两个替换对象 .

  • -10

    作为多态性的一个例子,另一种解决方案是创建实现常用方法的包装类 .

    class Stringish (str):
        def matches (self, input):
            return self == input
    
    class Regexish (re):
        def matches (self, input):
            return self.match(input)
    

    现在,您的代码可以遍历包含对象的 alloweds 列表,完全透明地实例化这两个类中的任何一个:

    for allowed in alloweds:
        if allowed.matches(input):
            ignored = False
            break
    

    另请注意一些代码重复是如何消失的(尽管您的原始代码可能已被重构以单独修复) .

  • 7

    仅供参考此类代码的示例在BeautifulSoup中:http://www.crummy.com/software/BeautifulSoup并使用'hasattr'技术 . 本着"alternative approach"的精神,你也可以通过这样做将你的字符串搜索封装在regexp中:regexp = re.compile(re.escape(your_string))因此只有一个正则表达式的列表 .

  • 0

    这是另一个问题的答案,但它解决了问题的反应 . 除非your_string包含正则表达式特殊字符,

    if re.match(your_string,target_string):
    

    具有相同的效果

    if your_string == target_string:
    

    因此,退回一步并在允许列表中使用未编译的正则表达式模式 . 这无疑比使用编译的正则表达式慢,但它只适用于偶然的意外结果,并且仅当您允许用户提供允许的项目时

  • 10
    >>> import re
    >>> regex = re.compile('foo')
    >>> regex
    <_sre.SRE_Pattern object at 0x10035d960>
    

    好吧 - _sre是进行模式匹配的C扩展...你可以查看_sre C源代码 .

    你为什么在乎?

    或者你尝试这样的事情(无论出于何种原因 - 我不在乎):

    >>> regex1 = re.compile('bar')
    >>> regex2 = re.compile('foo')
    >>> type(regex1) == type(regex2)
    True
    

相关问题