2015-04-06 124 views
0

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

输入:

(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 

注:我可以清洁在包括丑陋的方式文本大量的“替换”方法。不过,我更喜欢用更专业的方式清理它,或者使用嵌入斯坦福分析器API的工具。

回答

1

无法为斯坦福API说话,但是这可能是(相当),很容易用正则表达式来完成,如下面:

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

那么这是什么呢?

  • 首先,我们要确保我们实际想要匹配的文本前面有一个开括号,后面跟着一些大写字母,然后是一个空格。为此,我们使用逆序。例如,(?<=foo)bar将与“foobar”中的“bar”匹配,但不匹配“ackbar”或“bar”中的“bar”。在我们的例子中,我们使用一个转义的开括号\(填充lookbehind,然后至少一个+大写字母[A-Z],然后单个空格字符。因为(在理论上 - 我再也不知道斯坦福大学的解析器是如何处理事物的)短语可以由多个单词组成,或者可以用连字符或其他奇怪的方式标出,等等。所以我们利用反选择器^,它匹配除了它的选择器内的所有内容。例如,[^ABC]将匹配除大写A,B和C以外的所有字符。因此,我们只需匹配至少一个不包含结尾括号\)+字符,该字符将匹配所有字符,直到我们敲完圆括号。
  • 在上面的项目符号中引入的一个小错误是,它没有考虑嵌套的短语。匹配关闭圆括号将匹配(NP (NP (CD 25))中的(NP (CD 25,这显然不是我们想要的。所以我们也不允许匹配开头括号\(来解释这一点。

一切都很好,除了Java,使得事情比他们需要的更加困难。

  • 首先,Java的回顾后解析器不喜欢未知的可能长度的lookbehinds,出于某种原因。因此,我们必须将的[A-Z]+更改为使用长度范围,例如, [A-Z]{2,3},它将匹配大小为2-3个字符的字符串。 请注意,如果斯坦福分析器表示带有大于或小于大写字母的键的短语,则必须相应地调整该范围!
  • 接下来,必须在使用前编译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转换为某种类型的链接列表,具体取决于您的输入文本的长度。

+0

感谢@Diosjenin:这种反应是非常全面和伟大。它工作得很好。唯一需要的编辑是在解析器中我们有(NP(PRP $我们))(NN经济),所以这个解决方案将删除(PRP $我们),这是不正确的。通过删除所有$符号这种方法准确地工作 – user3147590

+0

@ user3147590,因为情况是这样的:在执行之前,不要删除$ s,你可以添加一个转义的$'\\ $'并在大写字母匹配后标记为可选的'?'。新的正则表达式将读为'(?<= \\ [AZ] {2,3} \\ $?)[^ \\(\\)] +',它将与“(PRP $ our)”中的“我们”相匹配 – Diosjenin

2

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

你得到一个是 “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的例子展示了如何在co上设置它使用-outputFormat标志mmand行:

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

我正在使用选区解析器 – user3147590

+0

I必须查看您的代码才能向您显示需要设置输出格式的位置。斯坦福分析器特别支持您所需的输出格式,您只需知道将其设置在哪里。 – leekaiinthesky