Python 如何从一篇文章或一堆段落中找到标题格短语

Python 如何从一篇文章或一堆段落中找到标题格短语,python,parsing,nlp,text-parsing,Python,Parsing,Nlp,Text Parsing,如何解析文章中的句子格短语 例如,从这段话 柯南·道尔说,福尔摩斯这个角色的灵感来自约瑟夫·贝尔博士,道尔曾在爱丁堡皇家医务室为他工作。与福尔摩斯一样,贝尔也以从最小的观察中得出大的结论而闻名。[1]迈克尔·哈里森在1971年《Ellery Queen's神秘杂志》上的一篇文章中指出,这个角色的灵感来自温德尔·谢勒(Wendell Scherer),他是一起谋杀案的咨询侦探,据称1882年在英国报纸上引起了极大的关注 我们需要产生像柯南·道尔、福尔摩斯、约瑟夫·贝尔博士、温德尔·谢尔等的东西 如

如何解析文章中的句子格短语

例如,从这段话

柯南·道尔说,福尔摩斯这个角色的灵感来自约瑟夫·贝尔博士,道尔曾在爱丁堡皇家医务室为他工作。与福尔摩斯一样,贝尔也以从最小的观察中得出大的结论而闻名。[1]迈克尔·哈里森在1971年《Ellery Queen's神秘杂志》上的一篇文章中指出,这个角色的灵感来自温德尔·谢勒(Wendell Scherer),他是一起谋杀案的咨询侦探,据称1882年在英国报纸上引起了极大的关注

我们需要产生像柯南·道尔、福尔摩斯、约瑟夫·贝尔博士、温德尔·谢尔等的东西


如果可能的话,我更喜欢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博士,您需要对字符串中的时间段表示满意,这允许您在爱丁堡皇家医务室进行检查。就像福尔摩斯


我有一个类似的问题:。

这种处理可能非常棘手。这段简单的代码几乎做了正确的事情:

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博士,您需要对字符串中的时间段表示满意,这允许您在爱丁堡皇家医务室进行检查。就像福尔摩斯


我遇到了一个类似的问题:。

重新方法很快就失去了动力。命名实体识别是一个非常复杂的主题,远远超出了SO答案的范围。如果你认为你有一个很好的解决这个问题的方法,请指出弗兰恩·奥布莱恩a.k.a.迈尔斯·纳科帕琳、苏加诺、哈里·S·杜鲁门、J·埃德加·胡佛、J·k·罗琳、数学家L'Hopital、乔·迪马吉奥、阿尔杰农·道格拉斯·蒙塔古·斯科特、雨果·马克斯·格拉夫·冯和祖·勒森菲尔德·奥夫·克费林和舍恩伯格

以下更新是一种基于re的方法,可以发现更多有效案例。不过,我仍然认为这不是一个好办法。注意,我已经在我的文本样本中确认了巴伐利亚伯爵的名字。如果有人真的想使用这样的东西,他们应该使用Unicode,并在输入或输出的某个阶段将空白标准化

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'

重新进近的动力很快就耗尽了。命名实体识别是一个非常复杂的主题,远远超出了SO答案的范围。如果你认为你有一个很好的解决这个问题的方法,请指出弗兰恩·奥布莱恩a.k.a.迈尔斯·纳科帕琳、苏加诺、哈里·S·杜鲁门、J·埃德加·胡佛、J·k·罗琳、数学家L'Hopital、乔·迪马吉奥、阿尔杰农·道格拉斯·蒙塔古·斯科特、雨果·马克斯·格拉夫·冯和祖·勒森菲尔德·奥夫·克费林和舍恩伯格

以下更新是一种基于re的方法,可以发现更多有效案例。不过,我仍然认为这不是一个好办法。注意,我已经在我的文本样本中确认了巴伐利亚伯爵的名字。如果有人真的想使用这样的东西,他们应该使用Unicode,并在输入或输出的某个阶段将空白标准化

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'

你能具体说明什么是句子格短语吗?不只是举个例子——虽然举个例子当然也很有用——你说的句子大小写到底是什么意思?我想OP想知道如何确定/解析哪些单词应该有大写字母。@ChrisW我想OP实际上想提取命名实体……你能具体说明句子的大小写短语是什么?不只是举个例子——虽然举个例子当然也很有用——你说的句子大小写到底是什么意思?我认为OP想知道如何确定/解析哪些单词应该有大写字母。@ChrisW我认为OP实际上想提取命名实体……请注意,这实际上是一个相当困难的问题就像霍姆斯在一般情况下犯的错误一样。对于OP,研究句子组块和命名实体提取以获取更多信息,并查看nltk。我确实想到了这个解决方案,但在尝试时遇到了一些误报,错过了一些真实案例。我漏掉的一个例子是,我们还需要看一些短语,比如物理学家萨格里与三联画的关联。NLP库(如NLTK)应用于命名实体识别。请注意,在一般情况下,修复类似Holmes错误的问题实际上相当困难。对于OP,研究句子组块和命名实体提取以获取更多信息,并查看nltk。我确实想到了这个解决方案,但在尝试时遇到了一些误报,错过了一些真实案例。我漏掉的一个例子是,我们还需要看一些短语,比如物理学家萨格里与三联画的关联。像NLTK这样的NLP库应该用于命名实体识别。