【发布时间】:2013-12-07 07:32:13
【问题描述】:
为什么grep 对待\n 和\\n 的方式相同?
例如,两者都匹配hallo\nworld。
grep("hallo\nworld", pattern="\n")
[1] 1
grep("hallo\nworld", pattern="\\n")
[1] 1
我看到hallo\nworld被解析成
hallo
world
也就是说,hallo 在一行上,world 在一行上。
那么在grep("hallo\nworld", pattern="\n") 中,pattern="\n" 是换行还是字面意义上的\n?
另请注意,其他人也会发生这种情况; \a \f \n \t \r 和 \\a \\f \\n \\t \\r 都被同等对待。但是\d\w\s不能用!为什么不呢?
我选择了不同的字符串进行测试,发现了正则表达式概念中的秘密。
转义有两种概念,一种是字符串转义,简单易懂;另一种是在正则模式表达式字符串中转义。在 R 中,grep(x, pattern=" some string here ")、\\n=\n= 等模式是换行符。但在普通字符串中,\\n!=\n,前者字面意思是\n,后者是换行符。我们可以通过以下方式证明这一点:
cat("\n")
cat("\\n")
\n>
如何证明这一点?我会尝试使用其他字符,而不仅仅是 \n,看看它们是否以相同的方式匹配。
special1 <- c( "\a", "\f", "\n", "\t", "\r")
special2 <- c("\\a","\\f","\\n","\\t","\\r")
target <- paste("hallo", special1, "world", sep="")
for (i in 1:5){
cat("i=", i, "\n")
if( grep(target[i], pattern=special1[i]) == 1)
print(paste(target[i], "match", special1[i], "succeed"))
if( grep(target[i], pattern=special2[i]) == 1)
print(paste(target[i], "match", special2[i], "succeed"))
}
输出:
i= 1
[1] "hallo\aworld match \a succeed"
[1] "hallo\aworld match `\\a` succeed"
i= 2
[1] "hallo\fworld match \f succeed"
[1] "hallo\fworld match `\\f` succeed"
i= 3
[1] "hallo\nworld match \n succeed"
[1] "hallo\nworld match `\\n` succeed"
i= 4
[1] "hallo\tworld match \t succeed"
[1] "hallo\tworld match `\\t` succeed"
i= 5
[1] "hallo\rworld match \r succeed"
[1] "hallo\rworld match `\\r` succeed"
请注意,\a \f \n \t \r 和 \\a \\f \\n \\t \\r 在 R 正则表达式字符串中的处理方式相同>
不仅如此,你不能在R正则表达式模式中写\d\w\s!
您可以编写以下任何一种:
pattern="\a" "pattern=\f" "pattern=\n" "pattern=\t" "pattern=\r"
但你不能写任何这些!
pattern="\d" "pattern="\w" "pattern=\s" in grep.
我认为这也是一个错误,因为 \d \w \s 被不平等对待 \a \f \n \t \r。
【问题讨论】:
-
其实反过来:
\n和\\n都匹配"hallo\nworld",或者更准确地说,是"hallo\nworld"的子串。另外,请更准确地回答您的问题:您想实现什么?你为什么要关心差异?是否存在pattern是用户输入的应用程序?简而言之,请更详细! (另外,在逗号之前加一个空格,在之后加一个空格,真的很碍眼。真的是“word”“comma”“space”“word”。)跨度> -
你为什么不写你最后的编辑作为答案?
-
如果你确信这是一个错误,那么你应该写信给R-devel。使用 SO 的 R Core 成员相对较少,因此他们不太可能在这里看到它。
-
就
\d、\w和\s而言,与\a、\f、\n、\t和\r的区别在于是字符类,而不是字符。字符转义序列在任何字符串中都有其含义,而字符类则没有。