[PYTHON] 파이썬 정규식 파스 스트림
PYTHON파이썬 정규식 파스 스트림
파이썬에서 스트림에 정규식 일치를 사용하는 방법이 있습니까? 처럼
reg = re.compile(r'\w+')
reg.match(StringIO.StringIO('aa aaa aa'))
그리고 나는 전체 문자열의 가치를 얻음으로써 이것을하고 싶지 않습니다. srtream (on-the-fly)에서 정규 표현식과 일치시키는 방법이 있는지 알고 싶습니다.
해결법
-
==============================
1.나는 똑같은 문제가 있었다. 첫 번째 생각은 LazyString 클래스를 구현하는 것입니다.이 클래스는 현재와 같이 스트림에서 많은 양의 데이터를 읽는 것뿐입니다 (나는 __getitem__ 및 __iter__을 다시 구현하여 액세스하여 액세스 한 가장 높은 위치까지 문자를 가져오고 버퍼링합니다.) ).
나는 똑같은 문제가 있었다. 첫 번째 생각은 LazyString 클래스를 구현하는 것입니다.이 클래스는 현재와 같이 스트림에서 많은 양의 데이터를 읽는 것뿐입니다 (나는 __getitem__ 및 __iter__을 다시 구현하여 액세스하여 액세스 한 가장 높은 위치까지 문자를 가져오고 버퍼링합니다.) ).
이것은 제대로 작동하지 않았다. (re.match에서 "TypeError : expected string or buffer"를 얻었 기 때문에) 표준 라이브러리에서 re 모듈의 구현을 조금 보았다.
불행히도 스트림에서 정규식을 사용하는 것은 불가능 해 보입니다. 모듈의 핵심은 C로 구현되어 있으며,이 구현은 전체 입력을 메모리에 한 번에 전달할 것으로 기대합니다 (주로 성능상의 이유로). 이 문제를 해결하는 쉬운 방법이없는 것 같습니다.
PYL (Python LEX / YACC)도 살펴 보았지만, 렉서는 내부적으로 re를 사용하므로이 문제를 해결할 수 없습니다.
파이썬 백엔드를 지원하는 ANTLR을 사용할 수도 있습니다. 순수 파이썬 코드를 사용하여 렉서를 구성하고 입력 스트림에서 작동 할 수있는 것 같습니다. 나에게 문제는 그다지 중요하지 않기 때문에 (나는 내 의견이 광범위하게 커질 것이라고 기대하지 않는다.), 나는 더 이상 조사하지 않을 것이지만, 한 번 볼 가치가있을 것이다.
-
==============================
2.특정 파일의 경우 mmap을 사용하여 파일을 메모리 맵핑 할 수 있고 유니 코드 대신 바이트 테스트로 작업하는 경우 메모리 맵핑 된 파일을 바이트 테스트로 전달할 수 있습니다. 그냥 일이야. 이것은 RAM이 아닌 주소 공간에 의해 제한되므로, 8GB RAM을 갖춘 64 비트 컴퓨터는 32GB 파일을 메모리 맵핑 할 수 있습니다.
특정 파일의 경우 mmap을 사용하여 파일을 메모리 맵핑 할 수 있고 유니 코드 대신 바이트 테스트로 작업하는 경우 메모리 맵핑 된 파일을 바이트 테스트로 전달할 수 있습니다. 그냥 일이야. 이것은 RAM이 아닌 주소 공간에 의해 제한되므로, 8GB RAM을 갖춘 64 비트 컴퓨터는 32GB 파일을 메모리 맵핑 할 수 있습니다.
이 작업을 수행 할 수 있다면 정말 좋은 옵션입니다. 할 수 없다면, 더 복잡한 옵션으로 전환해야합니다.
타사 regex 모듈 (re가 아닌)은 스트리밍 지원을 빌드하는 데 사용할 수있는 부분 일치 지원을 제공하지만 지저분하고주의해야 할 점이 많습니다. lookbehinds와 ^와 같은 것들은 작동하지 않을 것입니다. 너비가 맞지 않으면 일치하는 것이 까다로울 것입니다. 정규 표현식이 제공하는 다른 고급 기능과 올바르게 상호 작용하는지, 다시는 그렇지 않은지 잘 모릅니다. 여전히 사용 가능한 완벽한 솔루션에 가장 가까운 것 같습니다.
partial = True를 regex.match, regex.fullmatch, regex.search 또는 regex.finditer에 전달하면 정규식을보고하는 것 외에도 regex는 데이터가 확장 된 경우 일치하는 항목을보고합니다.
In [10]: regex.search(r'1234', '12', partial=True) Out[10]: <regex.Match object; span=(0, 2), match='12', partial=True>
더 많은 데이터가 일치 결과를 변경할 수 있다면 전체 일치 대신 부분 일치를보고합니다. 예를 들어 regex.search (r '[\ s \ S] *', anything, partial = True)는 항상 부분 일치.
이렇게하면 데이터 슬라이딩 창을 일치시킬 수 있습니다. 창이 끝나고 처음부터 소비 된 데이터를 버리면 확장 할 수 있습니다. 불행히도, 문자열의 시작 부분에서 사라지는 데이터에 의해 혼란 스러울 수있는 것은 작동하지 않으므로, lookbehinds, ^, \ b 및 \ B가 출력됩니다. 너비가 맞지 않는 경우 조심해야합니다. 다음은 파일 또는 파일과 같은 객체 위에 슬라이딩 윈도우를 사용하는 개념 증명입니다.
import regex def findall_over_file_with_caveats(pattern, file): # Caveats: # - doesn't support ^ or backreferences, and might not play well with # advanced features I'm not aware of that regex provides and re doesn't. # - Doesn't do the careful handling that zero-width matches would need, # so consider behavior undefined in case of zero-width matches. # - I have not bothered to implement findall's behavior of returning groups # when the pattern has groups. # Unlike findall, produces an iterator instead of a list. # bytes window for bytes pattern, unicode window for unicode pattern # We assume the file provides data of the same type. window = pattern[:0] chunksize = 8192 sentinel = object() last_chunk = False while not last_chunk: chunk = file.read(chunksize) if not chunk: last_chunk = True window += chunk match = sentinel for match in regex.finditer(pattern, window, partial=not last_chunk): if not match.partial: yield match.group() if match is sentinel or not match.partial: # No partial match at the end (maybe even no matches at all). # Discard the window. We don't need that data. # The only cases I can find where we do this are if the pattern # uses unsupported features or if we're on the last chunk, but # there might be some important case I haven't thought of. window = window[:0] else: # Partial match at the end. # Discard all data not involved in the match. window = window[match.start():] if match.start() == 0: # Our chunks are too small. Make them bigger. chunksize *= 2
-
==============================
3.이것은 오래된 문제인 것처럼 보입니다. 비슷한 질문에 게시 한 것처럼 내 솔루션 streamsearch-py의 Matcher 클래스를 서브 클래스 화하고 버퍼에서 정규식 일치를 수행 할 수 있습니다. 템플릿에 대한 kmp_example.py를 확인하십시오. 고전적인 Knuth-Morris-Pratt 매칭이 필요하다면이 작은 오픈 소스 라이브러리로 문제를 해결할 수 있습니다 :-)
이것은 오래된 문제인 것처럼 보입니다. 비슷한 질문에 게시 한 것처럼 내 솔루션 streamsearch-py의 Matcher 클래스를 서브 클래스 화하고 버퍼에서 정규식 일치를 수행 할 수 있습니다. 템플릿에 대한 kmp_example.py를 확인하십시오. 고전적인 Knuth-Morris-Pratt 매칭이 필요하다면이 작은 오픈 소스 라이브러리로 문제를 해결할 수 있습니다 :-)
-
==============================
4.예 - getvalue 메소드 사용 :
예 - getvalue 메소드 사용 :
import cStringIO import re data = cStringIO.StringIO("some text") regex = re.compile(r"\w+") regex.match(data.getvalue())
from https://stackoverflow.com/questions/4634376/python-regex-parse-stream by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬에서 두 날짜 문자열 비교하기 (0) | 2018.11.29 |
---|---|
[PYTHON] TypeError : b'1 '은 JSON 직렬 가능하지 않습니다. (0) | 2018.11.29 |
[PYTHON] root.destroy ()와 root.quit ()의 차이점은 무엇입니까? (0) | 2018.11.29 |
[PYTHON] 파이썬 unittest 프레임 워크에서 전역 변수 수정하기 (0) | 2018.11.29 |
[PYTHON] 어떻게하면 파이썬에서 램 디스크를 만들 수 있습니까? (0) | 2018.11.29 |