문제

구절에서 문장 문구를 구문 분석하는 방법은 어떻게하나요?

예를 들어이 구절에서

코난 도일 (Conan Doyle)은 홈즈 (Holmes)의 성격은 에딘버러 왕립 진료소에서 서기로 일한 조셉 벨 박사에게 영감을 받았다고 말했다. Holmes와 마찬가지로 Bell은 가장 작은 관찰에서 큰 결론을 내리는 것으로 유명했습니다. [1] Michael Harrison은 1971 년 Ellery Queen 's Mystery Magazine에서 1971 년 기사에서 캐릭터가 1882 년 영국에서 많은 신문에 주목을받은 살인 사건의 "컨설팅 형사"인 Wendell Scherer에서 영감을 받았다고 주장했다.

Conan Doyle, Holmes, Joseph Bell 박사, Wendell Scherr 등과 같은 물건을 생성해야합니다.

가능하다면 Pythonic 솔루션을 선호합니다

도움이 되었습니까?

해결책

이런 종류의 처리는 매우 까다로울 수 있습니다. 이 간단한 코드는 거의 옳은 일을합니다.

for s in re.finditer(r"([A-Z][a-z]+[. ]+)+([A-Z][a-z]+)?", text):
    print s.group(0)

생산 :

Conan Doyle
Holmes
Dr. Joseph Bell
Doyle
Edinburgh Royal Infirmary. Like Holmes
Bell
Michael Harrison
Ellery Queen
Mystery Magazine
Wendell Scherer
England

"Joseph Bell 박사"를 포함하려면 "Edinburgh Royal Infirmary. Like Holmes"에서 허용하는 끈의 기간에 대해서는 괜찮아 야합니다.

비슷한 문제가있었습니다. 문장 분리.

다른 팁

"RE"접근 방식은 증기가 매우 빠르게 진행됩니다. 명명 된 엔티티 인식은 SO 답변의 범위를 넘어서는 매우 복잡한 주제입니다. 이 문제에 대한 좋은 접근 방식이 있다고 생각되면 Flann O'Brien 일명 Myles Na Cgopaleen, Sukarno, Harry S. Truman, J. Edgar Hoover, JK Rowling, The Mathematician L 'Hopital, Joe di Maggio, Joe di Maggio를 지적하십시오. Algernon Douglas-Montagu-Scott 및 Hugo Max Graf von und Zu Lerchenfeld Auf Köfering und Schönberg.

업데이트 다음은 훨씬 더 유효한 경우를 발견하는 "Re"기반 접근법입니다. 그래도 나는 이것이 좋은 접근법이라고 생각하지 않습니다. NB 나는 내 텍스트 샘플에서 바이에른 카운트의 이름을 as습니다. 누군가가 실제로 이와 같은 것을 사용하고 싶다면 유니 코드에서 작동하고 어떤 단계 (입력 또는 출력에 따라) 공백을 정규화해야합니다.

import re

text1 = """Conan Doyle said that the character of Holmes was inspired by Dr. Joseph Bell, for whom Doyle had worked as a clerk at the Edinburgh Royal Infirmary. Like Holmes, Bell was noted for drawing large conclusions from the smallest observations.[1] Michael Harrison argued in a 1971 article in Ellery Queen's Mystery Magazine that the character was inspired by Wendell Scherer, a "consulting detective" in a murder case that allegedly received a great deal of newspaper attention in England in 1882."""

text2 = """Flann O'Brien a.k.a. Myles na cGopaleen, I Zingari, Sukarno and Suharto, Harry S. Truman, J. Edgar Hoover, J. K. Rowling, the mathematician L'Hopital, Joe di Maggio, Algernon Douglas-Montagu-Scott, and Hugo Max Graf von und zu Lerchenfeld auf Koefering und Schoenberg."""

pattern1 = r"(?:[A-Z][a-z]+[. ]+)+(?:[A-Z][a-z]+)?"

joiners = r"' - de la du von und zu auf van der na di il el bin binte abu etcetera".split()

pattern2 = r"""(?x)
    (?:
        (?:[ .]|\b%s\b)*
        (?:\b[a-z]*[A-Z][a-z]*\b)?
    )+
    """ % r'\b|\b'.join(joiners)

def get_names(pattern, text):
    for m in re.finditer(pattern, text):
        s = m.group(0).strip(" .'-")
        if s:
            yield s

for t in (text1, text2):
    print "*** text: ", t[:20], "..."
    print "=== Ned B"
    for s in re.finditer(pattern1):
        print repr(s.group(0))
    print "=== John M =="
    for name in get_names(pattern2, t):
        print repr(name)

산출:

C:\junk\so>\python26\python extract_names.py
*** text:  Conan Doyle said tha ...
=== Ned B
'Conan Doyle '
'Holmes '
'Dr. Joseph Bell'
'Doyle '
'Edinburgh Royal Infirmary. Like Holmes'
'Bell '
'Michael Harrison '
'Ellery Queen'
'Mystery Magazine '
'Wendell Scherer'
'England '
=== John M ==
'Conan Doyle'
'Holmes'
'Dr. Joseph Bell'
'Doyle'
'Edinburgh Royal Infirmary. Like Holmes'
'Bell'
'Michael Harrison'
'Ellery Queen'
'Mystery Magazine'
'Wendell Scherer'
'England'
*** text:  Flann O'Brien a.k.a. ...
=== Ned B
'Flann '
'Brien '
'Myles '
'Sukarno '
'Harry '
'Edgar Hoover'
'Joe '
'Algernon Douglas'
'Hugo Max Graf '
'Lerchenfeld '
'Koefering '
'Schoenberg.'
=== John M ==
"Flann O'Brien"
'Myles na cGopaleen'
'I Zingari'
'Sukarno'
'Suharto'
'Harry S. Truman'
'J. Edgar Hoover'
'J. K. Rowling'
"L'Hopital"
'Joe di Maggio'
'Algernon Douglas-Montagu-Scott'
'Hugo Max Graf von und zu Lerchenfeld auf Koefering und Schoenberg'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top