Python에서 희귀 단어를 탐지하는 구현 방법

WBOY
풀어 주다: 2016-12-05 13:27:14
원래의
1952명이 탐색했습니다.

솔루션 아이디어

가장 먼저 떠오르는 것은 Python의 정규 표현식을 사용하여 불법 문자를 일치시킨 다음 불법 레코드를 찾는 것입니다. 그러나 이상은 언제나 충만하지만 현실은 잔혹하다. 구현 과정에서 문자 인코딩과 Python의 내부 문자열 표현에 대한 지식이 부족하다는 사실을 발견했습니다. 이 기간 동안 나는 많은 함정을 겪었고, 결국에는 여전히 모호한 부분이 있었지만 마침내 전반적으로 명확한 이해를 얻었습니다. 앞으로 같은 장소에 빠지지 않도록 여기에 경험을 기록하세요.

다음 테스트 환경은 ArcGIS 10.3에 포함된 Python 2.7.8 환경입니다. 다른 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() 만큼 강력하지 않습니다.

인코딩 문제

파이썬 정규식의 기본 기능을 이해한 후에 남은 것은 희귀 단어와 불법 문자를 일치시키는 적합한 정규식을 찾는 것뿐입니다. 잘못된 문자는 다음 패턴을 사용하여 매우 간단하게 일치시킬 수 있습니다.

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

이것은 갑자기 나에게 또 다른 아이디어를 제공했습니다.

문자열 변환이 실패했다고 가정하면 이는 GB2312 문자 집합에 속하지 않는다는 의미입니까? 그래서 unicode => GB2312 함수를 사용하여 문자열 변환을 시도하고 UnicodeEncodeError 예외를 포착하여 희귀 단어를 식별했습니다. unicode_string.encode('GB2312')

최종 코드는 다음과 같습니다.

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
로그인 후 복사

요약

위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부나 업무에 조금이나마 도움이 되었으면 좋겠습니다. 궁금한 점이 있으시면 메시지를 남겨주세요.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿