如何将解析后的文本转换为纯文本

时间:2015-04-06 23:48:42

标签: java stanford-nlp text-processing

我使用斯坦福解析器解析了一个文本并提取了所有的名词短语。现在我需要将解析后的名词短语转换为纯文本:

输入:

(NP (DT the) (JJ dallas) (NN country) (NN club))
(NP (NP (CD 25) (NN cent)) (NP (NNP bingo)))

期待输出:

the dallas country club
Cd 25 cent bingo

注意:我可以用丑陋的方式清理文本,包括许多“替换”方法。但是,我更喜欢以更专业的方式清理它,或者使用嵌入在Stanford解析器API中的工具。

2 个答案:

答案 0 :(得分:2)

输出格式由传递给Stanford Parser的formatString构造函数的TreePrint确定。

你得到的是“oneline”选项:

(NP (DT the) (JJ dallas) (NN country) (NN club))
(NP (NP (CD 25) (NN cent)) (NP (NNP bingo)))

你想要的是“单词”:

the dallas country club
25 cent bingo

根据TreePrint javadoc,已知格式为:

oneline, penn, latexTree, xmlTree, words, wordsAndTags, rootSymbolOnly,
dependencies, typedDependencies, typedDependenciesCollapsed, collocations,
semanticGraph, conllStyleDependencies, conll2007

Stanford Parser homepage中的这个示例显示了如何使用-outputFormat标志在命令行上设置它:

java -mx200m edu.stanford.nlp.parser.lexparser.LexicalizedParser
-retainTMPSubcategories -outputFormat "wordsAndTags,penn,typedDependencies"
englishPCFG.ser.gz mumbai.txt

答案 1 :(得分:1)

不能代表斯坦福API,但这可以(相当)轻松地使用正则表达式完成,例如:

(?<=\([A-Z]+ )[^\(\)]+

这是做什么的?

  • 首先,我们要确保我们实际想要匹配的文本前面是一个开括号,后跟一些大写字母,然后是一个空格。为此,我们使用了lookbehind。例如,(?<=foo)bar将匹配&#34; bar&#34; in&#34; foobar&#34 ;,但不是&#34; ackbar&#34;或者只是&#34; bar&#34;。在我们的示例中,我们使用转义的圆括号\(填充后备,然后至少有一个+大写字母[A-Z],然后是一个空格字符
  • 匹配后续文本本身可能很棘手,因为(理论上 - 再次,我不知道斯坦福大学的解析器如何处理事情)短语可能包含多个单词,或者可能是连字符因此我们利用反选择器^,除了选择器中注明的内容之外,它还匹配所有内容。例如,[^ABC]将匹配除大写A,B和C之外的所有字符。因此,我们只匹配至少一个不是右括号+的{​​{1}}字符,它将匹配所有字符字符,直到我们到达右括号。
  • 上面的子弹中引入的一个小错误是,这不包括嵌套短语。简单地匹配右括号将匹配\)中的(NP (CD 25,这显然不是我们想要的。因此,我们也不允许对开头括号(NP (NP (CD 25))进行匹配以解释此问题。

一切都很好......除了Java之外,事情变得比他们需要的更困难。

  • 首先,由于某些原因,Java的lookbehind解析器并不像未知可能长度的外观。因此,我们必须更改\(中的+以使用长度范围,例如[A-Z]+,它将匹配长度为2-3个字符的大写字母。 请注意,如果斯坦福大学解析器表示密钥的大写字母比您在此处记下的更多或更少,则您必须相应地调整该范围!
  • 接下来,必须在使用前编译Java正则表达式。所述恭维的一部分是将转义字符转换为字符文字。但是,这会将[A-Z]{2,3}及其对应物转换为字面的开括号和右括号,然后正则表达式引擎会将其视为正则表达式括号,这将导致它失败。因此,必须在编译之前转义转义的反斜杠本身,将每个\(转换为\

所以我们的最终正则表达式是:

\\

然后它可以以某种方式输入Java ...

(?<=\\([A-Z]{2,3} )[^\\(\\)]+

...将每个正则表达式匹配添加到ArrayList的新元素中。

出于性能目的,您可能希望将该ArrayList转换为某种链接列表,具体取决于输入文本的长度。