13

在阅读了所有关于iconvand之后Encoding,我仍然感到困惑。

我正在抓取网页的源代码,我有一个如下所示的字符串:('pretty\u003D\u003Ebig'在 R 控制台中显示为'pretty\\\u003D\\\u003Ebig')。我想将其转换为 ASCII 字符串,应该是'pretty=>big'.

更简单地说,如果我设置

x <- 'pretty\\u003D\\u003Ebig'

如何执行转换x到 yield pretty=>big

有什么建议么?

4

7 回答 7

11

使用解析,但不评估结果:

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
于 2013-07-22T12:35:26.687 回答
8

stringi包:

> x <- 'pretty\\u003D\\u003Ebig'
> stringi::stri_unescape_unicode(x)
[1] "pretty=>big"
于 2017-01-29T17:47:15.430 回答
4

虽然已经接受了Hong ooi的回答,但还是忍不住思考parseeval是一个重量级的解决方案。此外,正如所指出的那样,它并不安全,尽管对于我的应用程序,我可以确信我不会得到危险的报价。

所以,我设计了一种替代的,有点残酷的方法:

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

欢迎任何简化!

于 2013-07-21T11:46:27.170 回答
2

一个用途eval(parse)

eval(parse(text=paste0("'", x, "'")))

当然,这有其自身的问题,例如必须手动转义字符串中的任何引号。但它应该适用于可能出现的任何有效的 Unicode 序列。

于 2013-07-20T21:12:14.743 回答
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 ...

(所以我想我仍然不清楚用例。)

于 2013-07-20T17:44:11.403 回答
1

我同情;过去我一直在为 R 和 unicode 文本而苦苦挣扎,但并不总是成功。如果您的数据在其中,x则首先尝试全局替换,如下所示:

x <- gsub("\u003D", "=>", x)

我有时会使用类似的结构

lapply(x, utf8ToInt)

查看高代码点在哪里,例如超过 150 的任何内容。这有助于我定位由不间断空格引起的问题,例如,这些空格似乎不时弹出。

于 2013-07-20T12:14:28.030 回答
1
> iconv('pretty\u003D\u003Ebig', "UTF-8", "ASCII")
[1] "pretty=>big"

但你似乎有额外的逃避

于 2013-07-20T14:05:39.830 回答