在某种程度上,Mukesh Kumar 和 GsusRecovery 提供的两个答案都有帮助,但并不完全正确。
document.replaceAll("[^\\u0009\\u000a\\u000d\\u0020-\\uD7FF\\uE000-\\uFFFD]", "");
似乎替换了所有无效字符。但 CoreNLP 似乎不支持更多。我通过在整个语料库上运行解析器来手动找出它们,这导致了:
document.replaceAll("[\\uD83D\\uFFFD\\uFE0F\\u203C\\u3010\\u3011\\u300A\\u166D\\u200C\\u202A\\u202C\\u2049\\u20E3\\u300B\\u300C\\u3030\\u065F\\u0099\\u0F3A\\u0F3B\\uF610\\uFFFC]", "");
所以现在我在将文档交给解析器之前运行两个replaceAll() 命令。完整的代码sn -p是
// remove invalid unicode characters
String tmpDoc1 = document.replaceAll("[^\\u0009\\u000a\\u000d\\u0020-\\uD7FF\\uE000-\\uFFFD]", "");
// remove other unicode characters coreNLP can't handle
String tmpDoc2 = tmpDoc1.replaceAll("[\\uD83D\\uFFFD\\uFE0F\\u203C\\u3010\\u3011\\u300A\\u166D\\u200C\\u202A\\u202C\\u2049\\u20E3\\u300B\\u300C\\u3030\\u065F\\u0099\\u0F3A\\u0F3B\\uF610\\uFFFC]", "");
DocumentPreprocessor tokenizer = new DocumentPreprocessor(new StringReader(tmpDoc2));
for (List<HasWord> sentence : tokenizer) {
List<TaggedWord> tagged = tagger.tagSentence(sentence);
GrammaticalStructure gs = parser.predict(tagged);
System.err.println(gs);
}
不过,这不一定是不受支持字符的完整列表,这就是我在GitHub 上打开issue 的原因。
请注意,CoreNLP 会自动删除那些不受支持的字符。我想预处理我的语料库的唯一原因是避免所有这些错误消息。
11 月 27 日更新
Christopher Manning 刚刚回复了我打开的GitHub Issue。使用类edu.stanford.nlp.process.TokenizerFactory; 有几种方法可以处理这些字符。以这个代码示例来标记一个文档:
DocumentPreprocessor tokenizer = new DocumentPreprocessor(new StringReader(document));
TokenizerFactory<? extends HasWord> factory=null;
factory=PTBTokenizer.factory();
factory.setOptions("untokenizable=noneDelete");
tokenizer.setTokenizerFactory(factory);
for (List<HasWord> sentence : tokenizer) {
// do something with the sentence
}
您可以将第 4 行中的noneDelete替换为其他选项。我在引用曼宁:
"(...) 完整的六个选项集,组合了是否记录无、第一个或全部警告,以及是否删除它们或将它们作为单个字符标记包含在输出中:noneDelete、firstDelete , allDelete, noneKeep, firstKeep, allKeep。”
这意味着,要保留字符而不收到所有这些错误消息,最好的方法是使用选项noneKeep。这种方式比任何删除这些字符的尝试都要优雅得多。