以下是让我困惑的例子:
select ' w' ~ '^\s\w$';
这导致“假”,但似乎应该是真的。
select ' w' ~ '^\\s\w*$';
这导致“真实”,但是:
感谢您的帮助!
答案 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$'
不匹配。