在 tm text-mining R-package 的源代码中,在文件transform.R中,有这个removePunctuation()
函数,目前定义为:
function(x, preserve_intra_word_dashes = FALSE)
{
if (!preserve_intra_word_dashes)
gsub("[[:punct:]]+", "", x)
else {
# Assume there are no ASCII 1 characters.
x <- gsub("(\\w)-(\\w)", "\\1\1\\2", x)
x <- gsub("[[:punct:]]+", "", x)
gsub("\1", "-", x, fixed = TRUE)
}
}
我需要解析和挖掘来自科学会议的一些摘要(从他们的网站以 UTF-8 格式获取)。摘要包含一些需要删除的 unicode 字符,尤其是在单词边界处。有通常的 ASCII 标点字符,还有一些 Unicode 破折号、Unicode 引号、数学符号……
文本中还有URL,其中的标点符号需要保留词内标点符号。tm的内置removePunctuation()
功能太激进了。
所以我需要一个自定义removePunctuation()
函数来根据我的要求进行删除。
我的自定义 Unicode 函数现在看起来像这样,但它没有按预期工作。我很少使用 R,所以在 R 中完成任务需要一些时间,即使是最简单的任务。
我的功能:
corpus <- tm_map(corpus, rmPunc = function(x){
# lookbehinds
# need to be careful to specify fixed-width conditions
# so that it can be used in lookbehind
x <- gsub('(.*?)(?<=^[[:punct:]’“”:±</>]{5})([[:alnum:]])'," \\2", x, perl=TRUE) ;
x <- gsub('(.*?)(?<=^[[:punct:]’“”:±</>]{4})([[:alnum:]])'," \\2", x, perl=TRUE) ;
x <- gsub('(.*?)(?<=^[[:punct:]’“”:±</>]{3})([[:alnum:]])'," \\2", x, perl=TRUE) ;
x <- gsub('(.*?)(?<=^[[:punct:]’“”:±</>]{2})([[:alnum:]])'," \\2", x, perl=TRUE) ;
x <- gsub('(.*?)(?<=^[[:punct:]’“”:±</>])([[:alnum:]])'," \\2", x, perl=TRUE) ;
# lookaheads (can use variable-width conditions)
x <- gsub('(.*?)(?=[[:alnum:]])([[:punct:]’“”:±]+)$',"\1 ", x, perl=TRUE) ;
# remove all strings that consist *only* of punct chars
gsub('^[[:punct:]’“”:±</>]+$',"", x, perl=TRUE) ;
}
它没有按预期工作。我想,它根本没有做任何事情。标点符号仍在术语文档矩阵中,请参阅:
head(Terms(tdm), n=30)
[1] "<></>" "---"
[3] "--," ":</>"
[5] ":()" "/)."
[7] "/++" "/++,"
[9] "..," "..."
[11] "...," "..)"
[13] "“”," "(|)"
[15] "(/)" "(.."
[17] "(..," "()=(|=)."
[19] "()," "()."
[21] "(&)" "++,"
[23] "(0°" "0.001),"
[25] "0.003" "=0.005)"
[27] "0.006" "=0.007)"
[29] "000km" "0.01)"
...
所以我的问题是:
- 为什么对我的 function(){} 的调用没有达到预期的效果?如何改进我的功能?
- R 的 perl 兼容正则表达式是否支持 Unicode 正则表达式模式类,例如 if
\P{ASCII}
或支持?\P{PUNCT}
我认为它们不是(默认情况下)PCRE: : "只有对各种 Unicode 属性的支持 \p 是不完整的,但最重要的是支持。"