如何将已解析的文本转换为纯文本
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
我已经使用 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