2017-02-13 512 views
0

我有一个包含随机值的文本类型的列。其中一些是数字,一些其他文本,以及其他一些混合的文本和数字。我试图将它们区分为:PostgreSQL,正则表达式来匹配带有数字值的文本字段

myfield is_numeric 
____________________ 
-4  true 
0004  true 
4.00  true 
dog  false 
D04  false 
04f  false 

其他是名称和其他字符串。我正在使用正则表达式

SELECT id, 
     myfield 
     (myfield::varchar~ '^-?[0-9]*.?[0-9]*$') is_numeric 
FROM mytable 

要告诉其行是否包含有效数字。但是,我注意到像D0404c这样的值对于那个正则表达式返回true,对于我的用例来说,这是一个误报。

这是怎么发生的?看起来^匹配不一定是整个值,而是任何有效的值的子字符串。但是,像D04f这样的值确实会返回false,因此即使该字段中存在数字子字符串,^$运营商的组合也正在完成其工作。

我暂时采取使用:

SELECT id, 
     myfield 
     (myfield::varchar ~ '^-?[0-9]*.?[0-9]*$' 
     AND myfield::varchar !~ '[^0-9\-\.]') is_numeric 
FROM mytable 

但这似乎inneficient(并且不排除双点),我还在想为什么正则表达式是正确地排除了开头的字符串和结束与一个非数字字符,而不合格返回true的字符串,只包含尾随或前导非数字字符。

+1

这里:''^ - ?[0-9] *。?[0-9] * $''这部分''?您想成为任何字符或字符'.'?如果是第二个,它应该被删除 –

回答

2

这会为你工作吗?

^-?[0-9]+\.?[0-9]*$ 

我asuming -0.07.5是无效的(双点存在)。

D04也会返回false。

原始正则表达式中的问题是,您不是逃避该点,所以它会匹配您的D04中的任何字符,包括D

希望它有帮助。

+0

OMG,我重复了那个正则表达式,我没有看到这个缺陷。非常感谢你。 – amenadiel