【问题标题】:Regex to split values in PostgreSQL正则表达式在 PostgreSQL 中拆分值
【发布时间】:2015-11-22 21:08:14
【问题描述】:

我有一个来自 PGSQL 数据库的值列表,看起来像这样:

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

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

上面的列表会根据 PG 的结果被拆分成这个布局:

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

到目前为止,凭借我不存在的正则表达式知识,我所能想到的就是:regexp_replace(fieldname, '[^A-Z]+', '', 'g'),它只是去掉了任何不是 A-Z 的东西,但我不能;不能在数字之前使用字符串值,或在它们之后。

【问题讨论】:

  • 请编辑您的问题以包含您目前编写的代码。
  • 到目前为止,我能想出的只有我几乎不存在的正则表达式知识,是这样的:regexp_replace(fieldname, '[^A-Z]+', '', 'g'),它只是去掉了任何不是 A-Z 的东西

标签: sql regex postgresql


【解决方案1】:

用于提取数字前的字符:

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

用于提取数字后的字符:

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

注意:

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

最终 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

【讨论】:

  • 谢谢 - 非常有意义。
  • 欢迎您,我在您接受答案后添加了更多信息。希望对您有所帮助。
【解决方案2】:

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

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

  1. 将数值前的所有非数字内容放入 1 列
  2. 数字值后的所有非数字内容进入 2 列

因此假设您有一个包含数值的值。

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 以供预览。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2014-10-27
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2013-08-11
    相关资源
    最近更新 更多