在Windows替换特殊符号

时间:2019-01-31 18:36:23

标签: r regex r-markdown

学生通常将作业问题从pdf或word文档粘贴到Rmarkdown中。但是,粘贴的文本通常包含用于项目符号,引号等的非ASCII字符。我过去曾使用gsub作为替换此类字符的函数的一部分,这似乎可以正常工作,但我遇到了现在又出现了问题。

下面显示的每对中的第一行可在macOS,Linux和Windows上使用。但是,非ASCII字符不允许包含在R包中的代码中。每对中的第二行适用于macOS和Linux,但不适用于Windows。

最好有一种通用的方法来处理这些类型的字符,而不仅仅是删除它们。

gsub("•", "*", "A big dot •")
gsub("\xE2\x80\xA2", "*", "A big dot •")

gsub("…", "...", "Some small dots …")
gsub("\xE2\x80\xA6", "...", "Some small dots …")

gsub("–", "-", "A long-dash –")
gsub("\xE2\x80\x93", "-", "A long-dash –")

gsub("’", "'", "A curly single quote ’")
gsub("\xE2\x80\x99", "'", "A curly single quote ’")

gsub("‘", "'", "A curly single quote ‘")
gsub("\xE2\x80\x98", "'", "A curly single quote ‘")

gsub("”", '"', "A curly double quote ”")
gsub("\xE2\x80\x9D", '"', "A curly double quote ”")

gsub("“", '"', "A curly double quote “")
gsub("\xE2\x80\x9C", '"', "A curly double quote “")

2 个答案:

答案 0 :(得分:2)

我们可以使用Encoding函数来检查字符的十六进制编码:

x <- c("•", "…", "–", "’", "‘", "”", "“")
y <- x

Encoding(y) <- "bytes"

> x
[1] "•" "…" "–" "’" "‘" "”" "“"

> cat(y)
\x95 \x85 \x96 \x92 \x91 \x94 \x93

然后我们可以在您的gsub中添加十六进制代码:

gsub("•", "*", "A big dot •")
gsub("[\x95\xE2\x80\xA2]", "*", "A big dot •")

gsub("…", "...", "Some small dots …")
gsub("[\x85\xE2\x80\xA6]", "...", "Some small dots …")

gsub("–", "-", "A long-dash –")
gsub("[\x96\xE2\x80\x93]", "-", "A long-dash –")

gsub("’", "'", "A curly single quote ’")
gsub("[\x92\xE2\x80\x99]", "'", "A curly single quote ’")

gsub("‘", "'", "A curly single quote ‘")
gsub("[\x91\xE2\x80\x98]", "'", "A curly single quote ‘")

gsub("”", '"', "A curly double quote ”")
gsub("[\x94\xE2\x80\x9D]", '"', "A curly double quote ”")

gsub("“", '"', "A curly double quote “")
gsub("[\x93\xE2\x80\x9C]", '"', "A curly double quote “")

还有stri_trans_general中的stringi

library(stringi)
stri_trans_general(x, "ascii")
# [1] "•"   "..." "-"   "'"   "'"   "\""  "\""

这似乎不适用于"•",但其余部分都适用。

请注意,我只在Windows而非其他操作系统上测试了此解决方案。

答案 1 :(得分:1)

在具有非美国语言设置gsub("[\x95\xE2\x80\xA2]", "*", "A big dot •")的系统上,可能会导致错误(例如,请参见下文)。

> gsub("[\x95\xE2\x80\xA2]", "*", "A big dot •") 
Error in gsub("[曗€", "*", "A big dot <U+2022>") : 
  invalid regular expression '[曗€', reason 'Missing ']''

但是,以下方法确实能很好地工作。

gsub("\u2022", "*", "A big dot •")
gsub("\u2026", "...", "Some small dots …")
gsub("\u2013", "-", "A long-dash –")
gsub("\u2019", "'", "A curly single quote ’")
gsub("\u2018", "'", "A curly single quote ‘")
gsub("\u201D", '"', "A curly double quote ”")
gsub("\u201C", '"', "A curly double quote “")

此外,stringi::stri_trans_general在具有美国语言设置的系统上也能很好地工作,但是在具有中文语言设置的系统上,下面显示的代码不能返回所需的结果,只是夹。不知道解决方案是什么。

stringi::stri_trans_general("夹", "ascii")
> stringi::stri_trans_general("夹", "ascii")
[1] " 1/4D"