R如何处理常规表达式中的特殊字符?

PAC*_*PAC 5 regex r

我对下面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)

Mat*_*eck 3

您的测试并未完全确定该问题。该问题具体与字符有关\xc2\xb0,所有其他特殊 UTF 字符例如\xc4\x88也会导致相同的问题。

\n\n

考虑到您的输入模式,奇怪的输出实际上始终是输入字符串的最后五个字符。因此,在最初的“良好”测试中添加另一个字符将表明该测试也给出了错误的结果:

\n\n
sub(pattern = ".*([[:digit:]]{5}).*", replacement = "\\\\1", x = "A\xc2\xb0C 01160a")\n[1] "1160a"\n
Run Code Online (Sandbox Code Playgroud)\n\n

该引用不会造成问题,而且是转移注意力。使用perl=TRUEuseBytes=TRUE也可以防止问题发生。

\n\n

我认为这个问题与 ?regexp 的以下摘录有关:

\n\n
 In UTF-8 mode the named character classes only match ASCII\n characters\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,预定义的字符类可能无法正确处理 UTF-8 文本。在这种情况下,[0-9]似乎[[:digit:]]工作正常,因为它不是预定义的类。

\n\n

不过,我仍然不太清楚是什么导致了最后 5 个字符的具体输出。我的猜测是,当字符串是 UTF-8 编码时,预定义的类会匹配所有内容,因为您可以使用模式获得相同的输出".*(.{5}).*"。但至少我们更好地了解了问题所在:处理 UTF-8 字符集的预定义字符类。

\n