Подтвердить что ты не робот

Тип скомпилированного объекта регулярного выражения в python

Каков тип скомпилированного регулярного выражения в python?

В частности, я хочу оценить

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

чтобы быть правдой, для целей самоанализа.

Одно из решений, которое у меня было, имело некоторую глобальную константу REGEX_TYPE = type(re.compile('')), но это не кажется очень изящным.

EDIT: Причина, по которой я хочу сделать это, состоит в том, что у меня есть список строк и скомпилированные объекты регулярных выражений. Я хочу "сопоставить" строку со списком,

  • для каждой строки в списке, попробуйте проверить равенство строки.
  • для каждого регулярного выражения в списке, попробуйте проверить, соответствует ли строка данному шаблону.

и код, который я придумал, был:

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
4b9b3361

Ответ 1

Если тип чего-то не уточнен, нет ничего плохого в использовании встроенного встроенного type для обнаружения ответа во время выполнения:

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

Обнаружение типа во время выполнения защищает вас от необходимости доступа к приватным атрибутам и к будущим изменениям типа возврата. Здесь нет ничего необычного в использовании type, хотя может быть что-то нелепое о желании узнать тип вообще.

Ответ 2

В 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 раньше была ошибка, требующая от вас сделать это:

assert issubclass(type(my_re), Pattern)

Который не гарантирует работу в соответствии с документацией и набором тестов.

Ответ 3

Можно сравнить скомпилированное регулярное выражение с 're._pattern_type'

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

>>True

Дает True, по крайней мере, в версии 2.7

Ответ 4

Отказ от ответственности: Это не предназначено как прямой ответ для ваших конкретных потребностей, а скорее что-то, что может быть полезно в качестве альтернативного подхода


Вы можете сохранить идеалы утиного ввода текста и использовать hasattr, чтобы определить, есть ли у объекта определенные свойства, которые вы хотите использовать. Например, вы можете сделать что-то вроде:

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

Ответ 5

Профилактика лучше, чем лечение. Не создавайте такой гетерогенный список в первую очередь. У вас есть set допустимых строк и список скомпилированных объектов регулярных выражений. Это должно сделать ваш код проверки лучше выглядеть и работать быстрее:

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

Если вы не можете избежать создания такого списка, посмотрите, есть ли у вас возможность изучить его один раз и создать два объекта замены.

Ответ 6

В качестве иллюстрации полиморфизма альтернативным решением является создание классов-оболочек, которые реализуют общий метод.

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

FYI пример такого кода находится в BeautifulSoup: http://www.crummy.com/software/BeautifulSoup и использует технику 'hasattr'. В духе "альтернативного подхода" вы также можете инкапсулировать свой поиск строк в регулярном выражении, выполнив следующее:   regexp = re.compile(re.escape(your_string)) поэтому имеет список только регулярных выражений.

Ответ 8

Это еще один не ответ на вопрос, но он решает проблему ответа. Если ваша строка не содержит специальных символов регулярного выражения,

if re.match(your_string,target_string):

имеет тот же эффект, что и

if your_string == target_string:

Так что отступите на один шаг и используйте нескомпилированные шаблоны регулярных выражений в своем списке разрешенных. Это, несомненно, медленнее, чем использование скомпилированных регулярных выражений, но будет работать только с непредвиденным непредвиденным результатом, и только в том случае, если вы позволите пользователям предоставлять разрешенные элементы

Ответ 9

В 3.7 вы можете использовать re.Pattern:

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

Ответ 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