我正在解析人类可读的科学文本,主要是在化学领域。我感兴趣的是将文本分成单词列表,科学术语(下面有更多内容)和标点符号。
因此,例如,我希望文本“你好,世界”。打破4个令牌:1)“你好”; 2)逗号; 3)“世界”和4)时期。请注意,空格不需要专门的令牌。
问题与“科学术语”有关:这些是化学式的名称,例如“1-甲基-4-苯基吡啶鎓”。任何学过化学的人都知道这些公式可能会很长,可能包含数字,短划线和逗号,有时甚至是括号,但我认为假设这些可爱的表达式不能包含空格是安全的。另外,我相信这些表达式必须以数字开头。我希望每个这样的表达式都作为单个标记出现。
今天我使用手动解析来查找以数字开头并以空格,换行符或标点符号后跟空格或换行符结尾的文本“块”。
我想知道是否有智能解决方案(正则表达式或其他)我可以用来根据上述规范对文本进行标记。我在使用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
.
答案 0 :(得分:2)
这将解决您当前的示例。它可以调整为更大的数据集。
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
.
"""
答案 1 :(得分:0)
可能有一个正则表达式解析你想要的东西,但我认为它不会非常易读/可维护。我的建议是使用像ANTLR这样的解析器生成器。我认为你必须抛弃你的概念,你可以使化学描述成为一个单一的标记,太复杂了。 ANTLR甚至有一个调试器,所以你可以看到为什么它没有解析你认为应该的东西,我认为不可能使用正则表达式。
此致
Sebastiaan
答案 2 :(得分:0)
我同意Sebastiaan Megens的观点,即正则表达式解决方案可能是可行的,但可能不具有可读性或可维护性,特别是如果您还不熟悉正则表达式。如果您坚持使用Python(我认为这是一个不错的选择),我会推荐pyparsing module。
如果您的解析需求应该增长或改变,额外的可维护性将非常方便。 (而且我相信很多人都会说“何时”而不是“如果”!例如,有人已经评论说你可能需要更复杂的概念来说明化学名称需要什么。也许你的要求已经是在你选择工具之前改变!)