최근 직장에서 필드에 희귀한 단어와 ~!@#$%^&*와 같은 일부 불법 문자가 포함되어 있는지 검색해야 하는 요구 사항이 발생했습니다. 이제 인터넷에서 정보를 검색하여 해결했습니다. 이제 필요한 분들이 참고하실 수 있도록 해결 과정과 샘플 코드를 공유하겠습니다. 아래를 살펴보겠습니다.
해결 방법
가장 먼저 떠오르는 것은 Python의 정규 표현식을 사용하여 불법 문자를 일치시킨 다음 불법 레코드를 찾는 것입니다. 그러나 이상은 언제나 충만하지만 현실은 잔혹하다. 구현 과정에서 문자 인코딩과 Python의 내부 문자열 표현에 대한 지식이 부족하다는 사실을 발견했습니다. 이 기간 동안 나는 많은 함정을 겪었고, 결국에는 여전히 모호한 부분이 있었지만 마침내 전반적으로 명확한 이해를 얻었습니다. 앞으로 같은 장소에 빠지지 않도록 여기에 경험을 기록하세요.
다음 테스트 환경은 ArcGIS 10.3에 포함된 Python 2.7.8 환경입니다. 다른 Python 환경도 적합하다는 보장은 없습니다.
Python 정규 표현식
파이썬의 정규 함수는 내장된 re 함수 라이브러리에서 제공되며 주로 3가지 함수를 사용합니다. re.compile()
은 재사용 가능한 정규식을 제공하며 match()
및 search()
함수는 일치하는 결과를 반환합니다. 둘의 차이점은 match()
는 지정된 위치부터 일치를 시작하고 search()
는 지정된 위치에서 뒤로 검색합니다. 일치하는 문자열을 찾을 때까지. 예를 들어, 다음 코드에서 match_result
는 첫 번째 문자 f부터 일치를 시작하고 일치에 실패하면 null 값을 반환합니다. search_result
은 일치하는 첫 번째 문자 a를 찾을 때까지 f에서 역방향으로 검색한 다음 그룹을 사용합니다. () 함수 출력 일치 결과는 문자 a입니다.
import re pattern = re.compile('[abc]') match_result = pattern.match('fabc') if match_result: print match_result.group() search_result = pattern.search('fabc') if search_result: print search_result.group()
위 구현에서는 먼저 패턴을 컴파일한 다음 매칭해야 합니다. 실제로 re.match(pattern, string)
함수를 직접 사용하여 동일한 기능을 구현할 수 있습니다. 그러나 직접 매칭 방식은 먼저 컴파일한 후 매칭하는 것만큼 유연하지 않다. 우선, 동일한 패턴으로 많은 양의 데이터를 매칭하면 매번 내부 컴파일이 필요하다는 뜻이다. 또한 성능 손실이 발생하며 re.match()
기능은 일치를 시작할 위치를 지정할 수 있는 pattern.match()
만큼 강력하지 않습니다.
인코딩 문제
파이썬 정규식의 기본 기능을 이해한 후에는 rare에 적합한 정규식을 찾는 일만 남았습니다. 단어와 불법 문자. 불법 문자는 매우 간단하게 다음 패턴을 사용하여 일치시킬 수 있습니다.
pattern = re.compile(r'[~!@#$%^&* ]')
그러나 희귀 문자의 일치는 정말 당황스럽습니다. 첫 번째는 희귀 단어의 정의입니다. 어떤 단어가 희귀하다고 간주되나요? 프로젝트 매니저와 협의한 결과, GB2312 이외의 캐릭터는 희귀 캐릭터로 판단되었습니다. 다음 질문은 GB2312 문자를 일치시키는 방법입니다.
질의 결과 GB2312의 범위는 [xA1-xF7][xA1-xFE]
이고, 한자 영역의 범위는 [xB0-xF7][xA1-xFE]
이다. 따라서 희귀 단어 매칭을 추가한 후의 표현은
pattern = re.compile(r'[~!@#$%^&* ]|[^\xA1-\xF7][^\xA1-\xFE]')
문제가 논리적으로 해결된 것 같지만 여전히 너무 단순하고 너무 순진합니다. 심사할 문자열은 모두 레이어 파일에서 읽혀지기 때문에 arcpy는 읽은 문자를 신중하게 유니코드 형식으로 인코딩합니다. 따라서 유니코드에서 GB2312 문자셋의 인코딩 범위를 알아내야 합니다. 그러나 실제로는 유니코드에서 GB2312 문자 집합의 분포가 연속적이지 않으며 정규식을 사용하여 이 범위를 표현하는 것은 매우 복잡해야 합니다. 희귀한 단어를 매칭하기 위해 정규 표현식을 사용한다는 아이디어는 막다른 골목에 도달한 것 같습니다.
해결 방법
제공된 문자열이 유니코드 형식이므로 GB2312로 변환한 후 일치시킬 수 있나요? 실제로 유니코드 문자 집합이 GB2312 문자 집합보다 훨씬 크기 때문에 불가능하므로 GB2312 => unicode
는 항상 달성될 수 있지만 반대로 unicode => GB2312
는 반드시 성공하지 못할 수도 있습니다.
이것은 갑자기 나에게 또 다른 아이디어를 제공했습니다. unicode => GB2312
문자열 변환이 실패한다고 가정하면 이는 GB2312 문자 집합에 속하지 않는다는 의미입니까? 그래서 unicode_string.encode('GB2312')
함수를 사용하여 문자열 변환을 시도하고 UnicodeEncodeError 예외를 포착하여 희귀 단어를 식별했습니다.
최종 코드는 다음과 같습니다.
import re def is_rare_name(string): pattern = re.compile(u"[~!@#$%^&* ]") match = pattern.search(string) if match: return True try: string.encode("gb2312") except UnicodeEncodeError: return True return False
요약
위 내용은 Python을 사용하여 희귀 단어를 감지하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!