program tip

파이썬에서 컴파일 된 정규식 객체의 유형

radiobox 2020. 11. 24. 07:50
반응형

파이썬에서 컴파일 된 정규식 객체의 유형


파이썬에서 컴파일 된 정규식의 유형은 무엇입니까?

특히 나는 평가하고 싶다

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

어떤 유형이 잘 지정되지 않은 경우 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.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)

문서 및 테스트 스위트에 따라 작동한다고 보장되지는 않습니다.


컴파일 된 정규 표현식을 're._pattern_type'과 비교할 수 있습니다.

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

>>True

적어도 2.7 버전에서 True를 제공합니다.


면책 조항 : 이것은 귀하의 특정 요구에 대한 직접적인 답변이 아니라 대체 접근 방식으로 유용 할 수있는 것입니다.


오리 타이핑의 이상을 유지 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

예방이 치료보다 낫습니다. 처음에 이러한 이기종 목록을 만들지 마십시오. 세트 허용 문자열과 컴파일 된 정규식 개체의 목록을. 이렇게하면 검사 코드가 더 좋아 보이고 더 빠르게 실행됩니다.

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

그러한 목록의 생성을 피할 수 없다면 한 번 검사하고 두 개의 대체 개체를 작성할 기회가 있는지 확인하십시오.


As an illustration of polymorphism, an alternate solution is to create wrapper classes which implement a common method.

class Stringish (str):
    def matches (self, input):
        return self == input

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

Now your code can iterate over a list of alloweds containing objects instantiating either of these two classes completely transparently:

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

Notice also how some code duplication goes away (though your original code could have been refactored to fix that separately).


FYI an example of such code is in BeautifulSoup: http://www.crummy.com/software/BeautifulSoup and uses the 'hasattr' technique. In the spirit of the "alternative approach", you might also encapsulate your string search in a regexp by doing this: regexp = re.compile(re.escape(your_string)) therefore having a list of only regular expressions.


This is another not the answer to the question, but it solves the problem response. Unless your_string contains regular expression special characters,

if re.match(your_string,target_string):

has the same effect as

if your_string == target_string:

So drop back one step and use uncompiled regular expression patterns in your list of allowed. This is undoubtedly slower than using compiled regular expressions, but it will work with only the occasional unexpected outcome, and that only if you allow users to supply the allowed items


In 3.7 you can use re.Pattern:

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

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

Well - _sre is a C extension doing the pattern matching...you may look in the _sre C source.

Why do you care?

Or you try something like this (for whatever reason - I don't care):

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

참고URL : https://stackoverflow.com/questions/6102019/type-of-compiled-regex-object-in-python

반응형