代码之家  ›  专栏  ›  技术社区  ›  Roee Adler

Python:关于解析人类可读文本的问题

  •  2
  • Roee Adler  · 技术社区  · 17 年前

    我正在分析人类可读的科学文本,主要是在化学领域。我感兴趣的是把课文分解成一系列单词、科学术语(下面有更多内容)和标点符号。

    例如,我希望文本“hello,world.”分成4个标记:1)“hello”;2) 逗号;3) “世界”和4)时期。请注意,空格不需要专门的标记。

    这个问题与“科学术语”有关:这些是化学式的名称,如“1-甲基-4-苯基吡啶”。任何学过化学的人都知道这些公式可能很长,可能包含数字、破折号和逗号,有时甚至还有括号,但我认为可以肯定的是,这些可爱的表达式不能包含空格。此外,我认为这些表达必须以数字开头。我希望每一个这样的表达都能作为一个单独的标记出现。

    今天,我使用手动解析来查找以数字开头,以空格、换行符或标点符号后跟空格或换行符结尾的文本“块”。

    我想知道是否有一个智能解决方案(regex或其他)可以用于根据上述规范标记文本。我正在使用Python,但这可能与语言无关。

    输入示例(显然忽略内容…):

    “您好。1-甲基-4-苯基吡啶非常糟糕。但是,1-甲基-4-苯基-1,2,3,6-四氢吡啶更糟糕。”

    输出示例(每个令牌在其自己的行中):

    Hello
    .
    1-methyl-4-phenylpyridinium
    is
    ultra
    -
    bad
    .
    However
    ,
    1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine
    is
    worse
    .
    
    3 回复  |  直到 17 年前
        1
  •  2
  •   Charles Beattie    17 年前

    这将解决您当前的示例。它可以调整为更大的数据集。

    import re
    splitterForIndexing = re.compile(r"(?:[a-zA-Z0-9\-,]+[a-zA-Z0-9\-])|(?:[,.])")
    source = "Hello. 1-methyl-4-phenylpyridinium is ultra-bad. However, 1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine is worse."
    print "\n".join( splitterForIndexing.findall(source))
    

    结果是:

    """
    Hello
    .
    1-methyl-4-phenylpyridinium
    is
    ultra-bad
    .
    However
    ,
    1-methyl-4-phenyl-1,2,3,6-tetrahydropyridine
    is
    worse
    .
    """
    

    对不起,我没看到太糟糕了。如果有必要把这些词分开。。

    import re
    splitterForIndexing = re.compile(r"(?:[a-zA-Z]+)|(?:[a-zA-Z0-9][a-zA-Z0-9\-(),]+[a-zA-Z0-9\-()])|(?:[,.-])")
    source = "Hello. 1-methyl-4-phenylpyridinium is ultra-bad. However, 1-methyl-4-phenyl-1,(2,3),6-tetrahydropyridine is worse."
    print "\n".join( splitterForIndexing.findall(source))
    

    给予:

    """
    Hello
    .
    1-methyl-4-phenylpyridinium
    is
    ultra
    -
    bad
    .
    However
    ,
    1-methyl-4-phenyl-1,(2,3),6-tetrahydropyridine
    is
    worse
    .
    """
    
        2
  •  0
  •   Sebastiaan M    17 年前

    可能会有一个正则表达式解析您想要的内容,但我认为它不太可读/可维护。我的建议是使用像ANTLR这样的解析器生成器。我认为你必须放弃这样的想法,你可以把化学描述变成一个单一的标记,太复杂了。ANTLR甚至有一个调试器,所以你可以看到为什么它没有解析你认为应该解析的东西,我认为使用regexps是不可能的。

    当做

        3
  •  0
  •   John Y    17 年前

    我同意Sebastiaan Megens的观点,正则表达式解决方案可能是可行的,但可能不太可读或可维护,特别是如果您还不擅长正则表达式的话。我推荐 pyparsing module ,如果您坚持使用Python(我认为这是一个不错的选择)。

    如果您的解析需求增长或改变,那么额外的可维护性将非常有用。(我相信很多人会说“什么时候”而不是“如果”!例如,有人已经评论说,你可能需要一个更复杂的概念来定义什么是化学名称。也许在你选择工具之前,你的要求已经发生了变化!)