正则表达式在PostgreSQL中分割值

时间:2015-11-22 21:08:15

标签: sql regex postgresql

我有一个来自PGSQL数据库的值列表,如下所示:

198
199
1S
2
20
997
998
999
C1
C10
A

我希望将这个字段解析成单个组件,我假设在我的SQL中需要两个regexp_replace函数。基本上,任何出现在数字之前的非数字字符都需要返回一列,而另一列则显示所有出现在数字之后的非数字字符。

上面的列表将作为PG的结果分成这个布局:

Table Format

我创建了一个删除非数字字符(最后一列)并将其强制转换为整数的函数,但是我无法弄清楚正则表达式在数字之前返回字符串值,或者那些在数字之后找到的人。

到目前为止,所有我能想到的,我的下一个不存在的正则表达式知识,是:regexp_replace(fieldname, '[^A-Z]+', '', 'g'),它只删除任何不是AZ的东西,但我可以;开始使用字符串在数值之前,或在它们之后。

2 个答案:

答案 0 :(得分:1)

用于提取数字前的字符:

regexp_replace(fieldname, '\d.*$', '')

用于提取数字后面的字符:

regexp_replace(fieldname, '^([^\d]*\d*)', '')

请注意:

  • 如果没有数字,第一个将返回原始值,然后是第二个空字符串。通过这种方式,您可以确保连接在这种情况下也等于原始值。
  • 如果有数字包围的非数字字符,则三部分的连接将不会返回原始字符:这些字符将丢失。
  • 这也适用于任何非字母数字字符,如@,[,! ...等等。

最终SQL

select
  fieldname as original,
  regexp_replace(fieldname, '\d.*$', '') as before_s,
  regexp_replace(fieldname, '^([^\d]*\d*)', '') as after_s,
  cast(nullif(regexp_replace(fieldname, '[^\d]', '', 'g'), '') as integer) as number
from mytable;  

请参阅fiddle

答案 1 :(得分:0)

此答案取决于您提供的信息,即

  

基本上,在数字之前出现的任何非数字字符   需要为一列返回,而另一列则返回   显示所有非数字字符出现在数字字符之后。

  1. 数字值为1列之前的所有非数字
  2. 数字值变为2列后的所有非数字
  3. 因此假设您有一个具有数值的值。

    select 
      val,
      regexp_matches(val,'([a-zA-Z]*)\d+') AS before_numeric,
      regexp_matches(val,'\d+([a-zA-Z]*)') AS after_numeric
    from 
      val;
    

    附加SQLFiddle进行预览。