在阅读了所有关于iconv
和Encoding
之后,我仍感到困惑。
我正在抓取web page的来源我有一个如下所示的字符串:'pretty\u003D\u003Ebig'
(在R控制台中显示为'pretty\\\u003D\\\u003Ebig'
)。我想将其转换为ASCII字符串,该字符串应为'pretty=>big'
。
更简单,如果我设置
x <- 'pretty\\u003D\\u003Ebig'
如何在x
上执行转换以产生pretty=>big
?
有什么建议吗?
答案 0 :(得分:9)
使用解析,但不评估结果:
x1 <- 'pretty\\u003D\\u003Ebig'
x2 <- parse(text = paste0("'", x1, "'"))
x3 <- x2[[1]]
x3
# [1] "pretty=>big"
is.character(x3)
# [1] TRUE
length(x3)
# [1] 1
答案 1 :(得分:5)
使用stringi
包:
> x <- 'pretty\\u003D\\u003Ebig'
> stringi::stri_unescape_unicode(x)
[1] "pretty=>big"
答案 2 :(得分:4)
虽然我接受了Hong ooi的回答,但我不禁想到parse
和eval
是一个重量级的解决方案。另外,正如所指出的那样,它并不安全,尽管对于我的应用程序,我可以确信我不会得到危险的报价。
所以,我设计了另一种有点残酷的方法:
udecode <- function(string){
uconv <- function(chars) intToUtf8(strtoi(chars, 16L))
ufilter <- function(string) {
if (substr(string, 1, 1)=="|") uconv(substr(string, 2, 5)) else string
}
string <- gsub("\\\\u([[:xdigit:]]{4})", ",|\\1,", string, perl=TRUE)
strings <- unlist(strsplit(string, ","))
string <- paste(sapply(strings, ufilter), collapse='')
return(string)
}
欢迎任何简化!
答案 3 :(得分:2)
用于eval(parse)
!
eval(parse(text=paste0("'", x, "'")))
这当然有其自身的问题,例如必须手动转义字符串中的任何引号。但它应该适用于任何可能出现的有效Unicode序列。
答案 4 :(得分:1)
x
,那么首先尝试全局替换,如下所示:
x <- gsub("\u003D", "=>", x)
我有时会使用像
这样的结构lapply(x, utf8ToInt)
查看高代码点的位置,例如任何超过150的东西。这有助于我找到由不间断的空间引起的问题,例如,它们似乎不时出现。
答案 5 :(得分:1)
> iconv('pretty\u003D\u003Ebig', "UTF-8", "ASCII")
[1] "pretty=>big"
但你似乎有一个额外的逃避
答案 6 :(得分:1)
这里的诀窍是'\\u003D'
实际上是6个字符,而你想要的'\u003D'
只是一个字符。进一步的技巧是,要匹配那些反斜杠,你需要在模式中使用双重转义的反斜杠:
gsub("\\\\u003D\\\\u003E", "\u003D\u003E", x)
#[1] "pretty=>big"
要用一个字符替换多个字符,您需要定位整个模式。你不能简单地删除一个反斜杠。 (由于您已经指出这是一个更普遍的问题,我认为答案可能在于修改您尚未描述的下载此文本的方法。)
当我加载函数和依赖项时,此代码有效:
> freq <- ngram(c('pretty\u003D\u003Ebig'), year_start = 1950)
>
> str(freq)
'data.frame': 59 obs. of 4 variables:
$ Year : num 1950 1951 1952 1953 1954 ...
$ Phrase : Factor w/ 1 level "pretty=>big": 1 1 1 1 1 1 1 1 1 1 ...
$ Frequency: num 1.52e-10 6.03e-10 5.98e-10 8.27e-10 8.13e-10 ...
$ Corpus : Factor w/ 1 level "eng_2012": 1 1 1 1 1 1 1 1 1 1 ...
(所以我想我仍然不清楚用例。)