确定Python对象是正则表达式还是字符串

时间:2014-12-08 20:05:28

标签: python regex

思考练习:什么是最好的"编写Python函数的方法,该函数采用正则表达式字符串来完全匹配:

import re
strings = [...]

def do_search(matcher):
  """
  Returns strings matching matcher, which can be either a string
  (for exact match) or a compiled regular expression object
  (for more complex matches).
  """
  if not is_a_regex_pattern(matcher):
    matcher = re.compile('%s$' % re.escape(matcher))

  for s in strings:
    if matcher.match(s):
      yield s

那么,实施is_a_regex_pattern()

的想法

5 个答案:

答案 0 :(得分:6)

您可以通过_sre.SRE_Pattern

访问re._pattern_type类型
if not isinstance(matcher, re._pattern_type):
    matcher = re.compile('%s$' % re.escape(matcher))

以下是演示:

>>> import re
>>> re._pattern_type
<class '_sre.SRE_Pattern'>
>>> isinstance(re.compile('abc'), re._pattern_type)
True
>>>

答案 1 :(得分:0)

  1. 不是字符串:

    def is_a_regex_pattern(s):
      return not isinstance(s, basestring)
    
  2. _sre.SRE_Pattern(虽然这不可导入,但使用粗字符串匹配):

    def is_a_regex_pattern(s):
      return s.__class__.__name__ == 'SRE_Pattern'
    
  3. 您可以重新编译SRE_Pattern,似乎来评估它。

    def is_a_regex_pattern(s):
      return s == re.compile(s)
    

答案 2 :(得分:0)

如果matcher有方法match

,您可以进行测试
import re

def do_search(matcher, strings):
    """
    Returns strings matching matcher, which can be either a string
    (for exact match) or a compiled regular expression object
    (for more complex matches).
    """
    if hasattr(matcher, 'match'):
        test = matcher.match
    else:
        test = lambda s: matcher==s

    for s in strings:
        if test(s):
            yield s

您不应使用全局变量,而是使用第二个参数。

答案 3 :(得分:0)

或者,将其设为quack

try:
    does_match = matcher.match(s)
except AttributeError:
    does_match = re.match(matcher.s)

if does_match:
    yield s

换句话说,将matcher视为已经是已编译的正则表达式。如果那样中断,那就把它当作需要编译的字符串来对待。

这称为Duck Typing。不是每个人agrees都应该像常规突发事件那样使用例外情况。这是ask-permission versus ask-forgiveness辩论。与大多数语言相比,Python的宽恕程度要高amenable

答案 4 :(得分:0)

在 Python 3.7 上,re._pattern_type 被重命名为 re.Pattern

https://stackoverflow.com/a/27366172/895245 因此在那时中断,因为 re._pattern_type 未定义。

虽然 re.Pattern 看起来更好,因此有望更稳定,但文档中根本没有提到它:https://docs.python.org/3/library/re.html#regular-expression-objects 所以依赖它可能不是一个好主意。

https://stackoverflow.com/a/46779329/895245 确实有些道理。但是哪一天 str 类添加了一个 .match 方法,它会做一些完全不同的事情? :-) 啊,无类型语言的乐趣。

所以我想我会去:

import re

_takes_s_or_re_type = type(re.compile(''))
def takes_s_or_re(s_or_re):
    if isinstance(s_or_re, _takes_s_or_re_type):
        return 0
    else:
        return 1

assert takes_s_or_re(re.compile('a.c')) == 0
assert takes_s_or_re('a.c') == 1

因为这只会在公共 API 中断时中断。

在 Python 3.8.0 上测试。