我有这个MTST
列,打印后会产生
[1] "<U+0391>G<U+03A1><U+0399><U+039D><U+0399><U+039F> "
[2] "<U+0391>G<U+03A7><U+0399><U+0391><U+039B><U+039F>S "
[3] "<U+0391><U+0399>G<U+0399><U+039D><U+0391> "
[4] "<U+0391><U+0399>G<U+0399><U+039F> "
[5] "<U+0391><U+0399><U+0394><U+0397><U+03A8><U+039F>S "
[6] "<U+0391><U+039A><U+03A4><U+0399><U+039F>(<U+03A0><U+03A1><U+0395><U+0392><U+0395><U+0396><U+0391>) "
[7] "<U+0391><U+039B><U+0395><U+039E><U+0391><U+039D><U+0394><U+03A1><U+039F><U+03A5><U+03A0><U+039F><U+039B><U+0397> "
[8] "<U+0391><U+039B><U+0399><U+0391><U+03A1><U+03A4><U+039F>S "
我尝试使用Unicode
库并执行MTST<- as.u_char(MTST)
提供
[1] <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
我也尝试了dump
和dput
但没有改变。
请注意,MTST
最初的类型为character
。
感谢您的帮助。感谢
显示<{1}}下面的编辑
dput(MTST)
答案 0 :(得分:6)
你所拥有的内容看起来像普通的7位ASCII字符,并试图通过包装其中的一些来编码Unicode代码点:<U+abcd>
。
据我所知,这不是Unicode的公认编码,部分原因是你如何在文本中加入真正的<
?我想每个<
可以是<U+jklm>
,其中jklm
是一个尖括号的代码......但是ick。
所以,首先,尝试从生成此ascii编码的混乱中获取UTF-8编码的字符串!
然而......经过一些严肃的头发拉动......
stringi
救援!在哪里&#39; MTST&#39;是你的东西,首先将尖括号表示法转换为反斜杠-u然后使用stri_unescape_unicode
:
> require(stringi)
> greek2=gsub(">","", gsub("<U\\+","\\\\u",MTST))
> stri_unescape_unicode(greek2)
[1] "ΑGΡΙΝΙΟ "
[2] "ΑGΧΙΑΛΟS "
[3] "ΑΙGΙΝΑ "
[4] "ΑΙGΙΟ "
[5] "ΑΙΔΗΨΟS "
[6] "ΑΚΤΙΟ(ΠΡΕΒΕΖΑ) "
一直到
[123] "FΥΧΤΙΑ "
[124] "ΧΑΛΚΙΔΑ "
[125] "ΧΑΝΙΑ "
[126] "ΧΙΟS "
[127] "ΧΡΥSΟΥΠΟΛΗ_ΚΑΒΑΛΑ "
[128] "OΡΕΟΙ "
一旦我在你的&#34; dput&#34;中修复了奇怪的逗号和引号。数据(为您编辑问题)。
答案 1 :(得分:2)
我已经在基地R中编写了一个方便,通用且内部稍微不稳定的功能,可以很好地实现此目的。这是:
dsub <- function(input,re,f=function(s,d) paste0(s,c(if (length(d)==0L) NULL else paste0('<',d,'>'),''),collapse='')) {
splits <- strsplit(input,re,perl=T);
delims <- lapply(strsplit(gsub(paste0('(',re,')'),'.\\1',input,perl=T),paste0('\\.(?=',re,')'),perl=T),function(x) sub(paste0('^(',re,').*'),'\\1',x[-1],perl=T))
lapply(1:length(splits), function(i) { s <- splits[[i]]; d <- delims[[i]]; f(c(s,if (length(s)==length(d)) '' else NULL),d); } );
};
该函数背后的想法是提供更强大的strsplit()
变体,它允许您不仅将输入字符串拆分为字段,而且为每个输入字符串设置一个lambda,该字符串同时接收两个字段列表(我在代码中称之为splits
或s
)以及分隔每个字段的分隔符(称为delims
或d
)。
重要的是,最终字段永远不会分隔,因此s
总是比d
长一个元素。现在,应该注意的是strsplit()
通常不是这样的;如果输入字符串中的最后一个分隔符包含所述字符串的结尾,它实际上并没有返回一个最后的空字符串字段,但是我已经修补了#34;#34;修补了&#34;为了保持一致性,我在dsub()
函数中的行为;对于lambda f()
的每次调用,保证s
比d
长一个元素。
第二个怪癖与我提取分隔符的方式有关;说起来容易做起来难。我再次使用strsplit()
,但是使正则表达式成为零宽度前瞻断言以保留分隔符内容,然后,在分割之后,我调用sub()
来去除分隔符后的所有内容。现在,当您使用匹配多个字符的完全零宽度正则表达式时,strsplit()
表现得很奇怪;我认为发生的事情是它在同一点上匹配正则表达式两次,然后在相邻的返回字段中拆分第一个和后续字符。为了解决这个问题,我在分隔符的每个实例之前添加了一个虚拟char,然后将该char(非零宽度,就在前瞻断言之前)作为分割正则表达式的一部分进行匹配,这自然会将其剥离。
无论如何,这是一个简单的演示,展示如何使用dsub()
与lambda调用intToUtf8()
来进行这种&#34; Unicode插值&#34;:
input <- c('Luc TR<U+00c9>HAN','aa<U+00ca>bb<U+00cb>cc','<U+00CC><U+00Cd>','',' ');
re <- '<U\\+([0-9a-fA-F]{4})>';
f <- function(s,d) paste0(s,c(if (length(d)==0L) NULL else intToUtf8(paste0('0x',sub(re,'\\1',d)),multiple=T),''),collapse='');
do.call(c,dsub(input,re,f));
## [1] "Luc TRÉHAN" "aaÊbbËcc" "ÌÍ" "" " "
使用此问题中给出的相当广泛的示例数据:
input <- c("<U+0391>G<U+03A1><U+0399><..."); ## (excerpted)
do.call(c,dsub(input,re,f));
## [1] "ΑGΡΙΝΙΟ " "ΑGΧΙΑΛΟS " "ΑΙGΙΝΑ " "ΑΙGΙΟ "
## [5] "ΑΙΔΗΨΟS " "ΑΚΤΙΟ(ΠΡΕΒΕΖΑ) " "ΑΛΕΞΑΝΔΡΟΥΠΟΛΗ " "ΑΛΙΑΡΤΟS "
## [9] "ΑΝΑΒΡΥΤΑ " "ΑΝΔΡΑΒΙΔΑ " "ΑΝOGΕΙΑ " "ΑΡΑΞΟS "
## [13] "ΑΡΑΧOΒΑ " "ΑΡGΟS(ΠΥΡGΕΛΑ) " "ΑΡGΟSΤΟΛΙ " "ΑΡΤΑ (ΠΟΛΗ) "
## [17] "ΑΡΤΑ (FΙΛΟTΕΗ) " "ΑSΤΕΡΟSΚΟΠΕΙΟ " "ΑSΤΡΟS " "ΑSΤΥΠΑΛΑΙΑ "
## [21] "ΒΑΜΟS " "ΒΕΛΟ (ΚΟΡΙΝTΙΑS) " "ΒΟΛΟS " "ΒΥΤΙΝΑ "
## [25] "GΟΡΤΥS " "GΥTΕΙΟ " "ΔΕSFΙΝΑ " "ΔΙΑΒΟΛΙΤSΙ "
## [29] "ΔΟΜΟΚΟS " "ΔΡΑΜΑ " "ΕΔΕSSΑ " "ΕΛΕΥSΙΝΑ "
## [33] "ΕΛΛΗΝΙΚΟ aeρ " "ΖΑΚΥΝTΟS " "ΖΑΚΥΝTΟS_ΠΟΛΗ " "ΖΑΡΟS "
## [37] "ΗΡΑΚΛΕΙΟ " "TΑSΟS " "TΗΡΑ (SΑΝΤΟΡΙΝΗ" "ΙΕΡΑΠΕΤΡΑ "
## [41] "ΙΚΑΡΙΑ_Α/Δ " "ΙOΑΝΝΙΝΑ " "ΚΑΒΑΛΑ (ΠΟΛΗ) " "ΚΑΒΑΛΑ(ΑΜΥGΔΑΛΕOΝΑS) "
## [45] "ΚΑΛΑΒΡΥΤΑ " "ΚΑΛΑΜΑΤΑ " "ΚΑΛΑΜΠΑΚΑ " "ΚΑΡΔΙΤSΑ "
## [49] "ΚΑΡΠΑTΟS_Α/Δ " "ΚΑΡΠΑTΟS_ΠΟΛΗ " "ΚΑΡΠΕΝΗSΙ " "ΚΑΡΥSΤΟS "
## [53] "ΚΑSΟS " "ΚΑSΤΕΛΛΙ " "ΚΑSΤΟΡΙΑ " "ΚΕΡΚΥΡΑ "
## [57] "ΚΟΖΑΝΗ " "ΚΟΜΟΤΗΝΗ " "ΚΟΝΙΤSΑ " "ΚΟΡΙΝTΟS "
## [61] "ΚΥTΗΡΑ_Α/Δ " "ΚΥΜΗ " "ΚOS " "ΚOS_ΠΟΛΗ "
## [65] "ΛΑΜΙΑ " "ΛΑΡΙSΑ " "ΛΕΡΟS " "ΛΕΥΚΑΔΑ (ΝΗSΙ) "
## [69] "ΛΕOΝΙΔΙΟ " "ΛΗΜΝΟS " "ΛΙΔOΡΙΚΙ " "ΜΑΚΕΔΟΝΙΑ "
## [73] "ΜΑΡΑTOΝΑS " "ΜΕTOΝΗ " "ΜΕSΟΛΟGGΙ " "ΜΗΛΟS_ΑΜS "
## [77] "ΜΥΚΟΝΟS " "ΜΥΤΙΛΗΝΗ " "ΝΑΞΟS " "ΝΑΥΠΑΚΤΟS "
## [81] "ΝΑΥΠΛΙΟ " "ΝΕΑ FΙΛΑΔΕΛFΕΙΑ " "ΞΑΝTΗ " "ΟΡΕSΤΙΑΔΑ "
## [85] "ΠΑΙΑΝΙΑ " "ΠΑΛΑΙΟΧOΡΑ " "ΠΑΡΟS_Α/Δ " "ΠΑΤΡΑ "
## [89] "ΠΕΙΡΑΙΑS " "ΠΟΛΥGΥΡΟS " "ΠΟΤΙΔΑΙΑ " "ΠΤΟΛΕΜΑΙΔΑ "
## [93] "ΠΥΡGΟS " "ΡΑFΗΝΑ " "ΡΕTΥΜΝΟ " "ΡΟΔΟS "
## [97] "SΑΜΟS " "SΕΔΕS " "SΕΡΡΕS " "SΗΤΕΙΑ "
## [101] "SΚΙΑTΟS " "SΚΟΤΙΝΑ " "SΚΥΡΟS " "SΟΥΔΑ "
## [105] "SΟΥFΛΙ " "SΠΑΡΤΗ " "SΠΑΤΑ(ΒΕΝΙΖΕΛΟS) " "SΠΕΤSΕS "
## [109] "SΤΕFΑΝΙ (ΚΟΡΙΝTΙΑS) " "SΥΚΥOΝΑ " "SΥΡΟS_Α/Δ " "ΤΑΝΑGΡΑ "
## [113] "ΤΑΤΟΙ (ΔΕΚΕΛΕΙΑ) " "ΤΖΕΡΜΙΑΔΕS " "ΤΡΙΚΑΛΑ ΗΜΑTΕΙΑS " "ΤΡΙΚΑΛΑ TΕSSΑΛΙΑS "
## [117] "ΤΡΙΠΟΛΗ " "ΤΥΜΠΑΚΙ " "ΤΥΡΙΝTΑ " "FΑΡSΑΛΑ "
## [121] "FΛOΡΙΝΑ " "FΟΥΡΝΗ " "FΥΧΤΙΑ " "ΧΑΛΚΙΔΑ "
## [125] "ΧΑΝΙΑ " "ΧΙΟS " "ΧΡΥSΟΥΠΟΛΗ_ΚΑΒΑΛΑ " "OΡΕΟΙ "
答案 2 :(得分:1)
这是恢复字符串中编码的真正解码字符的另一种方法(借用this question)。在这里,我们仔细匹配表单<U+[hex]>
并将该十六进制值展开为一个正确大小的unicode字符,并进行一些位操作。
trueunicode <- function(x) {
packuni<-Vectorize(function(cp) {
bv <- intToBits(cp)
maxbit <- tail(which(bv!=as.raw(0)),1)
if(maxbit < 8) {
rawToChar(as.raw(codepoint))
} else if (maxbit < 12) {
rawToChar(rev(packBits(c(bv[1:6], as.raw(c(0,1)), bv[7:11], as.raw(c(0,1,1))), "raw")))
} else if (maxbit < 17){
rawToChar(rev(packBits(c(bv[1:6], as.raw(c(0,1)), bv[7:12], as.raw(c(0,1)), bv[13:16], as.raw(c(0,1,1,1))), "raw")))
} else {
stop("too many bits")
}
})
m <- gregexpr("<U\\+[0-9a-fA-F]{4}>", x)
codes <- regmatches(x,m)
chars <- lapply(codes, function(x) {
codepoints <- strtoi(paste0("0x", substring(x,4,7)))
packuni(codepoints)
})
regmatches(x,m) <- chars
Encoding(x)<-"UTF-8"
x
}
使用样本
input <- c("<U+0391>G<U+03A1><U+0399><U+039D><U+0399><U+039F>", "<U+0391>G<U+03A7><U+0399><U+0391><U+039B><U+039F>S","<U+0391><U+0399>G<U+0399><U+039D><U+0391>", "<U+0391><U+0399>G<U+0399><U+039F>", "<U+0391><U+0399><U+0394><U+0397><U+03A8><U+039F>S","<U+0391><U+039A><U+03A4><U+0399><U+039F>(<U+03A0><U+03A1><U+0395><U+0392><U+0395><U+0396><U+0391>)")
你得到了
trueunicode(input)
# [1] "ΑGΡΙΝΙΟ" "ΑGΧΙΑΛΟS" "ΑΙGΙΝΑ" "ΑΙGΙΟ"
# [5] "ΑΙΔΗΨΟS" "ΑΚΤΙΟ(ΠΡΕΒΕΖΑ)"