2016-11-26 37 views
1

我想搜索基於地名數據庫,我可以用R:刪除

download.file('http://download.geonames.org/export/dump/IT.zip', destfile = 'IT.zip') 
unzip('IT.zip', exdir = 'IT') 
require(readr) 
it_gn <- read_delim("IT/IT.txt", "\t", escape_double = FALSE, col_names = FALSE, trim_ws = TRUE) 

欄上下載意大利地理實體文字寫在非拉丁字母的單詞(但包括附加符號)X4包括可供選擇地理名稱的版本,包括其他語言的版本。

例如

it_gn$X4[it_gn$X1 == 2522713] 
# [1] "Vittoira,Vittoria,vu~ittoria,ヴィットーリア" 

由於我對文檔的搜索是在意大利我想刪除寫入除拉丁字母其他字母的所有名稱,但包括意大利使用變音符號:-à , -è , -é , -ì , -ò , -ù-á , -í , -ó , -ú也(這些在意大利正式使用,但他們可能會出現)。但目前還不清楚我應該用哪個正則表達式來識別非拉丁字母。

我試圖申請this答案,但正則表達式似乎沒有任何區別...

grepl('[^\\x00-\\x7F]', 'ヴィットーリア') 
# [1] TRUE 

grepl('[^\\x00-\\x7F]', 'Vittoria') 
# [1] TRUE 

回答

4

首先,你的正則表達式不工作的原因是,正則表達式逃逸「\ XNN」是一個Perl的擴展,所以你需要通過「perl的= TRUE」,如果你想使用它:

> grepl('[^\\x00-\\x7F]', 'ヴィットーリア', perl=TRUE) 
[1] TRUE 
> grepl('[^\\x00-\\x7F]', 'Vittoria', perl=TRUE) 
[1] FALSE 
> 

(令人困惑的是,下面的工作:

> grepl('[^\x01-\x7F]', 'ヴィットーリア') 
[1] TRUE 
> grepl('[^\x01-\x7F]', 'Vittoria') 
[1] FALSE 
> 

,因爲沒有雙反斜線,你用R字符串文字的轉義序列「\ XNN」,而不是上述正則表達式轉義序列;這將嵌入給定的字節直接在字符串中,不管編碼如何,這是非常糟糕的做法,所以我會避免它這裏。)

話雖這麼說,我覺得最可讀的辦法是隻在您的R代碼裏面的Unicode字符:

isinvalid <- grepl('[^[:ascii:]àèéìòùáíóú]', name, 
        perl=TRUE, ignore.case=TRUE) 

perl=TRUE允許您使用[:ascii:]這儘管是醜陋的,似乎比更具可讀性如果您希望大寫字母的重音字符版本也被視爲有效,那麼替代方案和ignore.case=TRUE是必要的。

如果您的環境太搞砸了,包括統一在源代碼中,然後就可以正常使用「\ U」逃到它們包括:

isinvalid <- grepl('[^[:ascii:]\ue0\ue8\ue9\uec\uf2\uf9\ue1\ued\uf3\ufa]', name, 
        perl=TRUE, ignore.case=TRUE) 

請注意,你應該使用「\ U」逃逸而不是「\ x」在這裏轉義。這些是unicode代碼點,而不是直接插入到字符串中的字節。 (同樣,而奇怪的是,你也可以使用\\x逃逸,走的是Perl擴展的優勢,因爲 - 而令人困惑 - Perl的正則表達式「\ X」逃避行爲更如R的字符串文字「\ U」逃避而不是它的「 \ X」轉義。

啊...無論如何,我希望額外的解釋使事情更加明確而不是更少。

+0

在R''\ x20''中將顯示爲'「」'。我收到了一個關於nul字符的錯誤,但是你的'[^ \ x01- \ x7F]'是非常有幫助的。 –

0

在字符類的第一個位置使用脫字符否定它,這是不是有什麼你要。看到這個區別:

> grepl('[\\x00-\\x7F]', 'ヴィットーリア') 
[1] FALSE 
> 
> grepl('[\\x00-\\x7F]', 'Vittoria') 
[1] TRUE 

還有更多你的需求:

> sapply(strsplit('ヴィットーリア', ""), grepl, patt='[\\x00-\\x7F]') 
     [,1] 
[1,] FALSE 
[2,] FALSE 
[3,] FALSE 
[4,] FALSE 
[5,] FALSE 
[6,] FALSE 
[7,] FALSE 

對於我不明白原因,我需要使用較長PATT參數匹配小寫ASCII:

patt='[A-Za-z\\x00-\\x7F]' 

而且對於您的進一步觀點,我需要明確地包含這些變音符號的字符串。

> sapply(c('à' , 'è' , 'é' , 'ì' , 'ò' , 'ù' , 'á' , 'í' , 'ó' , 'ú'), grepl, patt='[A-Za-z\\x00-\\x7F]') 
    à  è  é  ì  ò  ù  á  í  ó  ú 
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 

所以,你可以嘗試:

patt = "[A-Za-zàèéìòùáíóú]" 

而且還可以決定是否要排除線路飼料和標籤。

+0

事實上,正如我在其他的答案,原因注意到\\ X逃逸不工作的是Perl正則表達式沒有被啓用,相反,你的正則表達式被視爲匹配反斜槓,「x」,「0」,「0」,「0」和反斜槓之間的任何字符,「x」,「7」或「F」,由於「0」和反斜槓之間的字符包含ASCII大寫字母,因此它與「Vittoria」匹配,但例如,它不會與全部小寫的「vitorria」相匹配。 –

+0

我應該使用'patt ='[\\ x01 - \\ xFF]',perl = TRUE)'。針對所有的ASCII和變音符號。 –