gpt4 book ai didi

java - 如何从 java 中的字符串中删除无效的 unicode 字符

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:13:19 25 4
gpt4 key购买 nike

我正在使用 CoreNLP Neural Network Dependency Parser解析一些社交媒体内容。不幸的是,根据 fileformat.info,该文件包含的字符是, 不是有效的 unicode 字符或 unicode 替换字符。这些是例如 U+D83DU+FFFD .如果这些字符在文件中,coreNLP 会使用如下错误消息进行响应:

Nov 15, 2015 5:15:38 PM edu.stanford.nlp.process.PTBLexer next
WARNING: Untokenizable: ? (U+D83D, decimal: 55357)

基于 this回答,我试过 document.replaceAll("\\p{C}", ""); 只是删除那些字符。 document 这里只是作为字符串的文档。但这没有帮助。

如何在将字符串传递给 coreNLP 之前从字符串中删除这些字符?

更新(11 月 16 日):

为了完整起见,我应该提到我问这个问题只是为了通过预处理文件来避免大量错误消息。 CoreNLP 只是忽略它无法处理的字符,所以这不是问题。

最佳答案

在某种程度上,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() 命令。完整的代码片段是

// 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);
}

不过,这不一定是不支持字符的完整列表,这就是我打开 issue 的原因在 GitHub .

请注意,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 替换为其他选项。我引用曼宁的话:

"(...) the complete set of six options combining whether to log a warning for none, the first, or all, and whether to delete them or to include them as single character tokens in the output: noneDelete, firstDelete, allDelete, noneKeep, firstKeep, allKeep."

这意味着,要保留字符而不收到所有这些错误消息,最好的方法是使用选项 noneKeep。这种方式比任何删除这些字符的尝试都要优雅得多。

关于java - 如何从 java 中的字符串中删除无效的 unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33722024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com