代码之家  ›  专栏  ›  技术社区  ›  ramdaz

如何从一段或一堆段落中查找标题框短语

  •  1
  • ramdaz  · 技术社区  · 16 年前

    我如何解析一段文章中的句子短语。

    例如,从这一段

    柯南·道尔说,福尔摩斯的性格受到约瑟夫·贝尔博士的启发,道尔曾在爱丁堡皇家医务室做过文员。与福尔摩斯一样,贝尔也因从最小的观察中得出大的结论而闻名于世[1]迈克尔·哈里森在1971年的《埃勒里女王的神秘》杂志上发表的一篇文章中指出,这个角色的灵感来自于一个名叫温德尔·谢勒的“咨询侦探”,据说他是1882年在英国的一个谋杀案中受到了报纸的广泛关注。

    我们需要创造像柯南·道尔,福尔摩斯,约瑟夫·贝尔博士,温德尔·谢尔等东西。

    如果可能的话,我更喜欢吃蟒蛇水

    2 回复  |  直到 16 年前
        1
  •  5
  •   Ned Batchelder    16 年前

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

    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
    

    要包括“约瑟夫·贝尔博士”,你需要确定字符串中的句号,它允许在“爱丁堡皇家医务室”。像福尔摩斯一样。

    我也有类似的问题: Separating Sentences .

        2
  •  2
  •   John Machin Santi    16 年前

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

    更新 下面是一个“重新”的方法,它可以找到更多有效的案例。不过,我仍然认为这不是一个好方法。注意,我已经在我的文本样本中说明了巴伐利亚计数的名称。如果有人真的想使用类似的东西,他们应该使用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'