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

How to convert a parsed text into a plain text

我已经使用 Stanford 解析器解析了文本并提取了所有名词短语。现在我需要将我解析的名词短语转换为纯文本:

输入:

(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

注意:我可以用包含很多 "replace" 方法的丑陋方式清理文本。但是,我更喜欢以更专业的方式或使用 Stanford 解析器中嵌入的工具来清理它 API。

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

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

那么这是做什么的?

  • 首先,我们要确保我们实际要匹配的文本前面有一个左括号,后面跟着一些大写字母,然后是 space。为此,我们使用回顾。例如,(?<=foo)bar 将匹配 "foobar" 中的 "bar",但不匹配 "ackbar" 或只是 "bar"。在我们的例子中,我们用一个转义的左括号 \( 填充 lookbehind,后跟至少一个 + 大写字母 [A-Z],然后是一个 space 字符 </code>.</li> <li>匹配后续文本本身可能会很棘手,因为(理论上 - 同样,我不知道斯坦福的解析器如何处理事情)短语可能包含多个单词,或者它可能被连字符或以其他方式奇怪地标点符号等等。因此我们利用了反选择器 <code>^,它匹配除选择器中注明的内容之外的所有内容。例如,[^ABC] 将匹配除大写字母 A、B 和 C 之外的所有字符。因此我们只需匹配至少一个不是右括号 \)+ 字符,这将匹配所有字符字符,直到我们点击右括号。
  • 上述项目符号中引入的一个小错误是它没有考虑嵌套短语。简单地匹配右括号将匹配(NP (NP (CD 25))中的(NP (CD 25,这显然不是我们想要的。因此,我们也不允许匹配左括号 \( 来说明这一点。

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

  • 首先,出于某种原因,Java 的后视解析器不喜欢未知可能长度的后视。所以我们必须更改 [A-Z]+ 中的 + 以使用长度范围,例如[A-Z]{2,3},它将匹配 2-3 个字符长的大写字母字符串。 请注意,如果 Stanford 解析器用比您在此处记录的大写字母更多或更少的键表示短语,您将必须相应地调整该范围!
  • 接下来,Java 正则表达式必须在使用前编译。所述编译的一部分是将转义字符转换为字符文字。但这会将 \( 及其对应项变成文字左括号和右括号,然后正则表达式引擎会将其视为正则表达式括号,这将导致它失败。所以转义的反斜杠本身必须在编译之前转义,将每个 \ 变成 \.

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

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

然后它可以像这样以某种方式被送入Java...

import java.util.regex.Matcher;
import java.util.regex.Pattern;

...

public ArrayList<String> GetMatchesFromNLP(String text) {
  ArrayList<String> matches = new ArrayList<String>();
  Matcher m = Pattern.compile("(?<=\([A-Z]{2,3} )[^\(\)]+").matcher(text);
  while (m.find()) {
    matches.add(m.group());
  }
}

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

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

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

您得到的是 "oneline" 选项:

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

你要的是"words":

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