Типа скомпилированный объект регулярных выражений в Python
каков тип скомпилированного регулярного выражения в python?
в частности, я хочу оценить
isinstance(re.compile(''), ???)
чтобы быть правдой, для целей интроспекции.
одно решение у меня было, есть некоторые глобальные константы REGEX_TYPE = type(re.compile(''))
, но это не кажется очень элегантным.
EDIT: почему я хочу сделать это потому, что у меня есть список строк, и скомпилированных объектов regex. Я хочу "сопоставить" строку со списком, на
- для каждой строки в списке, попробуйте для проверки равенства строк.
- для каждого регулярного выражения в списке попробуйте проверить, соответствует ли строка заданному шаблону.
и код, который я придумал:
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 ответов:
когда тип чего-то не очень хорошо указан, нет ничего плохого в использовании
type
строение, чтобы найти ответ во время выполнения:>>> import re >>> retype = type(re.compile('hello, world')) >>> isinstance(re.compile('goodbye'), retype) True >>> isinstance(12, retype) False >>>
обнаружение типа во время выполнения защищает вас от необходимости доступа к частным атрибутам и от будущих изменений возвращаемого типа. Нет ничего неэлегантного в использовании
type
здесь, хотя может быть что-то неэлегантное о желании знать тип вообще.
Python 3.5 представил
typing
модуль. В него входитtyping.re.Pattern
, a_TypeAlias
.начиная с Python 3.6, вы можете просто сделать:
from typing.re import Pattern my_re = re.compile('foo') assert isinstance(my_re, Pattern)
в 3.5, там был ошибка требуя от вас сделать это:
assert issubclass(type(my_re), Pattern)
который не гарантирует работу в соответствии с документацией и набором тестов.
можно сравнить скомпилированное регулярное выражение с ' re._pattern_type'
import re pattern = r'aa' compiled_re = re.compile(pattern) print isinstance(compiled_re, re._pattern_type) >>True
дает True, по крайней мере в версии 2.7
отказ от ответственности: Это не предназначено как прямой ответ для ваших конкретных потребностей, а скорее что-то, что может быть полезно в качестве альтернативного подхода
Вы можете сохранить с идеалами утка набрав, и использовать
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
профилактика лучше, чем лечение. Не создавайте такой разнородный список в первую очередь. Есть set разрешенных строк и списка скомпилированных объектов регулярных выражений. Это должно сделать ваш код проверки выглядеть лучше и работать быстрее:
if input in allowed_strings: ignored = False else: for allowed in allowed_regexed_objects: if allowed.match(input): ignored = False break
Если вы не можете избежать создания такого списка, посмотрите, есть ли у вас возможность изучить его один раз и построить два объекта замены.
в качестве иллюстрации полиморфизма альтернативным решением является создание классов-оболочек, которые реализуют общий метод.
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
заметьте также, как некоторое дублирование кода уходит (хотя ваш исходный код может быть переработан, чтобы исправить это отдельно).
FYI пример такого кода находится в BeautifulSoup:http://www.crummy.com/software/BeautifulSoup и использует технику 'hasattr'. В духе "альтернативного подхода" вы также можете инкапсулировать свой поиск строк в регулярное выражение, выполнив это: регулярное выражение = ре.компиляции(ре.escape(your_string)) поэтому есть список только регулярных выражений.
Это еще один не ответ на вопрос, но это решает проблему ответ. Если your_string не содержит специальных символов регулярного выражения,
if re.match(your_string,target_string):
аналогично
if your_string == target_string:
поэтому отступите на один шаг и используйте несжатые шаблоны регулярных выражений в своем списке разрешенных. Это, несомненно, медленнее, чем использование скомпилированных регулярных выражений, но он будет работать только с случайным неожиданным результатом, и это только если вы разрешить пользователям поставлять разрешенные элементы
>>> import re >>> regex = re.compile('foo') >>> regex <_sre.SRE_Pattern object at 0x10035d960>
Well-_sre-это расширение C, выполняющее сопоставление шаблонов...вы можете посмотреть в источнике _sre C.
почему тебя это волнует?
или вы попробуете что - то вроде этого (по какой-то причине-мне все равно):
>>> regex1 = re.compile('bar') >>> regex2 = re.compile('foo') >>> type(regex1) == type(regex2) True