2013-07-20 31 views
8

Dopo aver letto tutto su iconv e Encoding, sono ancora confuso.Conversione di una stringa Unicode con escape in ASCII

Sto raschiando la fonte di un web page Ho una stringa simile a questa: 'pretty\u003D\u003Ebig' (visualizzata nella console R come 'pretty\\\u003D\\\u003Ebig'). Voglio convertire questo nella stringa ASCII, che dovrebbe essere 'pretty=>big'.

Più semplicemente, se ho impostato

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

Come si esegue una conversione sul x a cedere pretty=>big?

Qualche suggerimento?

+0

Il codice che si sta utilizzando potrebbe essere necessaria per replicare questo problema. –

risposta

7

Usa parsing, ma non valutare i risultati:

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

'as.character (x2)' funzionerà anche e sarà vettorializzato (ad es .: 'as.character (parse (text = paste0 (" '", rep (x1,3),"' ")))'). Anche 'shQuote (x1)' potrebbe essere utile invece di 'paste0'. – Marek

1

I sympathize; Ho faticato con R e testo unicode in passato e non sempre con successo. Se i dati sono in x quindi in primo luogo cercare una sostituzione globale, qualcosa di simile:

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

volte uso una costruzione come

lapply(x, utf8ToInt) 

per vedere dove i punti di codice alti sono per esempio qualcosa di più di 150. Questo mi aiuta a individuare i problemi causati da spazi non interrotti, per esempio, che sembrano saltar fuori ogni tanto.

+1

Avrei bisogno di usare 'x <- gsub (" \ u003D \ u003E "," => ", x)' ma preferirei non coprire ogni possibile caso. Si noti che 'lapply (x, utf8ToInt)' restituisce '112 114 101 116 116 121 92 48 48 51 68 92 117 48 48 51 69 98 105 103' in modo che siano tutti punti di codice basso! Ho solo bisogno di annullare la tua escaping! – seancarmody

+0

Ah, buon punto, di solito sto affrontando le sceneggiature asiatiche che fanno guadagnare punti alti, questo è chiaramente un po 'diverso. – SlowLearner

0
> iconv('pretty\u003D\u003Ebig', "UTF-8", "ASCII") 
[1] "pretty=>big" 

ma sembrano avere una via di fuga in più

+0

Esattamente! Non posso aiutare la fuga extra: questo è ciò che restituisce la [pagina web] (http://books.google.com/ngrams/graph?content=pretty%3D%3Ebig&year_start=1800&year_end=2000&corpus=15) (fai clic su guarda la fonte e scorri verso il basso fino ai dati). – seancarmody

+0

È anche istruttivo confrontare 'cat ('pretty \ u003D \ u003Ebig')' e 'cat ('pretty \\ u003D \\ u003Ebig')'. Esiste una grande differenza tra le fughe nei dati inseriti nella console e le fughe nei dati ottenuti tramite altri mezzi. – seancarmody

+0

stai usando Windows? – user1609452

0

Il trucco è che è in realtà '\\u003D' 6 caratteri mentre si vuole '\u003D' che è solo un carattere. L'ulteriore trucco è che corrispondano a quelli backslash è necessario utilizzare backslash doppiamente sfuggiti nel modello:

gsub("\\\\u003D\\\\u003E", "\u003D\u003E", x) 
#[1] "pretty=>big" 

Per sostituire più personaggi con un carattere è necessario indirizzare l'intero modello. Non puoi semplicemente cancellare una barra rovesciata. (Dal momento che hai indicato che questo è un problema più generale, la risposta potrebbe risiedere in modifiche al tuo metodo ancora non descritto per scaricare questo testo.)

Quando carico le tue funzioni e le dipendenze, questo codice funziona:

> 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 ... 

(quindi credo che io non sono ancora chiare sul caso d'uso.)

+0

Il dettaglio cruento di dove sta accadendo il download è [qui] (https://github.com/seancarmody/ngramr/blob/master/R/ngram.R), ma funziona solo con 'x <- 'pretty \\ u003D \\ u003Ebig'' ti consente di riprodurre il problema. – seancarmody

+0

Avevo bisogno di identificare l'origine per più errori di funzione mancanti e caricato RCurl, stringr, httr e RJSONIO prima che potesse funzionare. Ho provato con un po 'del tuo codice commentato al di sopra di quelle funzioni, ma non sono ancora sicuro di avere un caso di test su cui lavorare. –

+0

La chiamata rilevante che genera l'errore è 'ngram (" pretty => big ")', ma il riferimento a questo pacchetto era solo per mostrare la motivazione: è troppo per un esempio riproducibile! – seancarmody

1

un uso per eval(parse)!

Questo ha naturalmente i suoi problemi, come dover sfuggire manualmente qualsiasi virgoletta all'interno della stringa. Ma dovrebbe funzionare per tutte le sequenze Unicode valide che possono apparire.

+0

Fortunatamente, data la [origine delle stringhe] (x <- 'pretty \\ u003D \\ u003Ebig') le virgolette sono già sterilizzate. – seancarmody

+0

Ho incorporato la correzione nel mio [pacchetto ngram] (https://github.com/seancarmody/ngramr). Grazie! – seancarmody

+0

Ho chiesto informazioni sull'igienizzazione qui: http://stackoverflow.com/questions/17770093/sanitising-strings-in-r –

3

Anche se ho accettato la risposta di Hong ooi, non posso fare a meno di pensare a parse e eval è una soluzione pesante. Inoltre, come sottolineato, non è sicuro, anche se per la mia applicazione posso essere sicuro che non otterrò virgolette pericolose.

Così, ho messo a punto un'alternativa, un po 'brutale, approccio:

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

eventuali semplificazioni accolto con favore!

3

Con il pacchetto stringi:

> x <- 'pretty\\u003D\\u003Ebig' 
> stringi::stri_unescape_unicode(x) 
[1] "pretty=>big"