我对下面3个测试的输出感到困惑:
这个包括一个特殊字符«°»并给出了良好的结果:
sub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\1", x = "A°C 01160")
[1] "01160"
Run Code Online (Sandbox Code Playgroud)
这个包括一个引用,并给出了良好的结果:
sub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\1", x = "01160 'aa")
[1] "01160"
Run Code Online (Sandbox Code Playgroud)
但是这个包括°和引用并返回一个奇怪的结果
sub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\1", x = "A°C 01160 'aa")
[1] "0 'aa"
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果我给出与向量相同的输入,结果也不一样,我也感到困惑:
sub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\1", x = c("A°C 01160", "01160 'aa", "A°C 01160 'aa"))
[1] "01160" "0 'aa" "0 'aa"
Run Code Online (Sandbox Code Playgroud)
有没有人有线索了解我的问题的根源?
我在Mac OS 10.8上使用法语UTF-8编码选项运行R 3.02:
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-apple-darwin10.8.0 (64-bit)
locale:
[1] fr_FR.UTF-8/fr_FR.UTF-8/fr_FR.UTF-8/C/fr_FR.UTF-8/fr_FR.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.0.2
Run Code Online (Sandbox Code Playgroud)
您的测试并未完全确定该问题。该问题具体与字符有关\xc2\xb0,所有其他特殊 UTF 字符例如\xc4\x88也会导致相同的问题。
考虑到您的输入模式,奇怪的输出实际上始终是输入字符串的最后五个字符。因此,在最初的“良好”测试中添加另一个字符将表明该测试也给出了错误的结果:
\n\nsub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\\\1", x = "A\xc2\xb0C 01160a")\n[1] "1160a"\nRun Code Online (Sandbox Code Playgroud)\n\n该引用不会造成问题,而且是转移注意力。使用perl=TRUE或useBytes=TRUE也可以防止问题发生。
我认为这个问题与 ?regexp 的以下摘录有关:
\n\n In UTF-8 mode the named character classes only match ASCII\n characters\nRun Code Online (Sandbox Code Playgroud)\n\n因此,预定义的字符类可能无法正确处理 UTF-8 文本。在这种情况下,[0-9]似乎[[:digit:]]工作正常,因为它不是预定义的类。
不过,我仍然不太清楚是什么导致了最后 5 个字符的具体输出。我的猜测是,当字符串是 UTF-8 编码时,预定义的类会匹配所有内容,因为您可以使用模式获得相同的输出".*(.{5}).*"。但至少我们更好地了解了问题所在:处理 UTF-8 字符集的预定义字符类。