我想根据地理名称数据库搜索意大利地理实体的文本,我可以用
下载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
答案 0 :(得分: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
是必需的也被视为有效。
如果您的环境过于紧张,无法在源代码中包含Unicode,那么您可以使用普通的“\ 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”逃脱。
呃...无论如何,我希望额外的解释能使更多明确而不是更少。
答案 1 :(得分: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àèéìòùáíóú]"
并决定是否要排除换行符和标签。