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

时间:2011-05-23 19:34:33

标签: python regex types

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

特别是,我想评估

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

是真实的,为了内省目的。

我有一个解决方案,有一些全局常量REGEX_TYPE = type(re.compile('')),但它似乎不太优雅。

编辑:我想这样做的原因是因为我有字符串列表和编译的正则表达式对象。我希望通过

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

我提出的代码是:

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

10 个答案:

答案 0 :(得分:36)

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

从Python 3.6开始,您只需执行以下操作:

from typing import Pattern

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

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

assert issubclass(type(my_re), Pattern)

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

答案 1 :(得分:31)

如果没有明确指定某事物的类型,使用type内置函数在运行时发现答案没有错:

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

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

答案 2 :(得分:19)

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

进行比较
import re
pattern = r'aa'
compiled_re = re.compile(pattern)
print isinstance(compiled_re, re._pattern_type)

>>True

至少在版本2.7中给予真实

答案 3 :(得分:15)

免责声明:这不是针对您的特定需求的直接答案,而是可能作为替代方法有用的内容


您可以遵循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

答案 4 :(得分:10)

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

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

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

答案 5 :(得分:7)

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

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

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

答案 6 :(得分:3)

仅供参考这个代码的一个例子是BeautifulSoup:http://www.crummy.com/software/BeautifulSoup并使用'hasattr'技术。 根据“替代方法”的精神,您可以通过执行以下操作将字符串搜索封装在正则表达式中:     regexp = re.compile(re.escape(your_string)) 因此只有一个正则表达式列表。

答案 7 :(得分:0)

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

if re.match(your_string,target_string):

具有相同的效果
if your_string == target_string:

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

答案 8 :(得分:0)

在3.7中,您可以使用re.Pattern

import re
rr = re.compile("pattern")
isinstance(rr, re.Pattern)
>> True

答案 9 :(得分:-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