在postgreSQL中,为什么\ s与\ w不同?

时间:2013-12-03 15:50:20

标签: regex postgresql

以下是让我困惑的例子:

select ' w' ~ '^\s\w$';

这导致“假”,但似乎应该是真的。

select ' w' ~ '^\\s\w*$';

这导致“真实”,但是:

  1. 为什么需要额外的反斜杠?
  2. 如果确实如此,为什么不需要额外的反斜杠?
  3. 感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我认为你以错误的方式测试了它,因为我得到了相反的结果。

select ' w' ~ '^\s\w$';

在我的情况下返回1。这实际上是有道理的,因为它匹配文本开头的空格,然后是最后的字母。

select ' w' ~ '^\\s\w*$';

正在返回0,这也是有意义的。在这里,您尝试匹配文本开头的反斜杠,然后是s,然后是任意数量的字母,数字或下划线。

与您的第二个正则表达式匹配的文本将是:'\sw'

检查小提琴here

答案 1 :(得分:0)

某些语言使用反斜杠作为转义字符。正则表达式就是这样,类似C的语言就是这样做的,一些稀有和奇怪的SQL方言就是这样做的。 PostgresSQL does it。 PostgresSQL正在转换反斜杠转义以获得字符串值,然后将该字符串值提供给正则表达式解析器,AGAIN转换为第一次转换后存活的反斜杠 - 如果有的话。在你的第一个正则表达式中,没有一个。

例如,在字符串文字或正则表达式中,\n并不表示反斜杠后跟小写字母n。这意味着换行。根据语言的不同,反斜杠后跟小写字母s将表示只是小写s或什么都不是。在PostgresSQL中,字符串文字中的无效转义序列转换为转义字符:'\w'转换为'w'。所有正则表达式解析器都看到w。偶然的是,您在匹配的字符串中使用了字母w。它与左值中的w不匹配,因为它是一个单词字符;它匹配它,因为它是一个小写的w。将其更改为小写x,它将停止匹配。

如果要在字符串文字中添加反斜杠,则需要使用另一个反斜杠转义它:'\\'。这就是你的第二个正则表达式\\s起作用的原因。如果要将任何单词字符与该字符匹配,请向\w添加第二个反斜杠。

这是一种可怕的痛苦。这就是为什么JavaScript,Perl和其他语言对正则表达式文字(如/\s\w/)有特殊约定,以及为什么C#程序员使用@"string literal"功能来禁用它们打算用作正则表达式的字符串中的反斜杠转义。

答案 2 :(得分:0)

字符串常量首先被解析并解释为字符串,包括转义字符。不识别序列的转义由不同的解析器以不同方式处理,但通常除了错误之外,最常见的行为是忽略反斜杠。

在第一个示例中,右侧字符串常量首先被解释为'^sw$',其中\s\w都不是可识别的字符串转义序列。

在第二个示例中,右手常量被解释为'^\sw*$' \\s转义\

解释字符串后,它们将被应用为正则表达式,'^\sw*$'匹配' w''^sw$'不匹配。