我有一个应用程序,我一直在努力,今晚发现了一个令人不安的差异 - 我想我会在这里记录它,看看是否有人可以复制它和/或解释它。查询已组成,但演示了问题:
select
'123' ~ '^\d+$' as result_1,
'123' ~ '^[0-9]+$' as result_2
我在Windows 7上运行PostgreSQL v9.1,当我运行此查询时,我得到:
T,T
然而,当我在Ubuntu 10.04上运行PostgreSQL v9.0上的查询时,我得到:
F,T
因此,看起来PostgreSQL在处理“\ d”时在v9.0和v9.1之间发生了变化,或者它在Windows和Ubuntu之间安装的lib之间存在差异。
无论哪种方式,我认为民间应该意识到你的检查限制等可能在两者之间的行为不一样(我确定没有)。
注意:遗憾的是,我无法轻松访问运行9.0的Windows 7机箱,或者我也会在那里进行测试。
任何人都能解释一下吗?如果它是众所周知的,请原谅我。当我用Google搜索时,我没有看到答案。显然,安全的做法是使用[0-9]因为它在两个位置都有效。但是,我想再次知道为什么会这样。
答案 0 :(得分:2)
你有逃避问题。来自fine 9.1 manual on string quoting:
如果配置参数
standard_conforming_strings
关闭,则PostgreSQL会识别常规字符串常量字符串和转义字符串常量中的反斜杠转义符。但是,从PostgreSQL 9.1开始,默认设置为on,这意味着反斜杠转义仅在转义字符串常量中被识别。
所以9.1看到'\d'
的方式与C的方式相同,只是看起来像'd'
。在9.1中你想要逃避反斜杠并使用E''
“escape”字符串表示法来过standard_conforming_strings
:
select
'123' ~ E'^\\d+$' as result_1,
'123' ~ '^[0-9]+$' as result_2
或者您可以尝试dollar quoting:
select
'123' ~ $re$^\d+$$re$ as result_1,
'123' ~ '^[0-9]+$' as result_2
但这很丑陋且难以用正则表达式阅读(尤其是使用$
来锚定结尾的正则表达式。)
另一种选择是使用POSIX character class代替\d
:
select
'123' ~ '^[[:digit:]]+$' as result_1,
'123' ~ '^[0-9]+$' as result_2
您应该在早期版本中看到有关'\d'
的警告,请检查您的日志中是否有以下内容:
WARNING: nonstandard use of escape in a string literal
LINE 1: select '\d';
^
HINT: Use the escape string syntax for escapes, e.g., E'\r\n'.