【问题标题】:PostgreSQL various clean up of string \ varcharPostgreSQL 各种字符串\varchar 的清理
【发布时间】:2013-01-02 23:20:46
【问题描述】:

我必须通过以下方式清理一些 varchar:

  1. 从关闭的列表中删除特殊字符,例如:!, @, #, $, %, ^, &, *, (, ), }, {, [, ], ",", ., ?, /, ',。我通过大量使用 replace\regexp_replace 设法做到了这一点,但我正在寻找类似于 SQL Server 中的东西。

  2. 删除以下数字但不相邻的含义:

    round 1 --> round
    round1 --> round1
    round 12345 --> round
    round12345 --> round12345

  3. 从封闭的单词列表中删除单词,例如:“and”、“or”、“Ltd.”、“international”,不带子字符串:

    more food or drinks ---> more food drinks. and not --> me food or drinks

我在一张大桌子上工作,我希望尽可能高效。
我应该写一个函数来做到这一点还是有更优雅的方式?

【问题讨论】:

  • 顺便说一句,您的第三个问题定义不明确。 “有限公司”中的点可以是句尾的点,也可以是缩写后的点。
  • 你说得对,“。”不应在 (3.) 中,因为它已在 (1.) 中删除
  • @ErwinBrandstetter 和 Tometzky 谢谢你们。我希望我能将所有答案都打勾。

标签: sql regex postgresql pattern-matching


【解决方案1】:

1。 最好用空格替换不允许列表中的字符,如下所示:

select regexp_replace(
    E'aśx€ ąsd, dsa w|adwf\n  as dw dgaa[aw] asdd',
    '[^a-zA-Z0-9]',
    ' ',
    'g');

返回

a x   sd  dsa w adwf   as dw dgaa aw  asdd

Unicode 中有数千个可能的字符——实际上不可能列出所有的特殊字符。

取出多个连续的空格作为练习留给读者。

【讨论】:

  • 多个问题需要多个答案。这是问题 1 的答案。
  • 其实:多个问题不应该放在一个问题中。
【解决方案2】:

我会一起玩的。以下是问题 2

SELECT trim(regexp_replace(
   '12 foo1 run 1457 ABC 1Foo 2456 bar 34',
   '\s*\m\d+\M\s*',
   ' ',
   'g'
   ));

返回:

foo1 run ABC 1Foo bar

我更新了答案以使用 约束表达式 而不是 括号表达式,因为手册告知:

下面描述的约束转义通常是可取的;他们 不再标准,但更容易输入。

\s* .. 零个或多个空格
\m .. 单词开头(与[[:<:]] 相同)
\d+ .. 1 个或多个数字
\M .. 词尾(同[[:>:]]

需要第 4 个参数 'g' 来替换“全局”,而不仅仅是第一次出现。

->sqlfiddle for v9.2
->sqlfiddle for v8.4 不起作用

为什么?

standard_conforming_strings。 v9.1 更改了默认值。

在两个世界中都有效,可以说是“兼容模式”。但是上面现代版本的语法(结合standard_conforming_strings = on)更简洁。

SELECT trim(regexp_replace(
  '12 foo1 run 1457 ABC 1Foo 2456 bar 34',
  E'\\s*\\m\\d+\\M\\s*',
  ' ',
  'g'
));

->sqlfiddle

【讨论】:

  • 我已经更正了 Erwin 的答案,因为它会在字符串的开头和结尾留下数字。
  • @Tometzky:谢谢,我清理了空白区域。
  • 这个恐怕不行。我仍然从中得到'12 foo1 run 1457 ABC 1Foo 2456 bar 34'。会不会是我正在使用的 postgresql 版本(8.2.15)?
  • @gilibi:我添加了解释、演示和另一个版本。
  • @gilibi:酷。顺便说一句:v8.2 已在 2011 年达到 EOL。您需要升级到更新的版本。除此之外,您至少应该升级到最后一个版本 8.2.23,这可以在没有转储/恢复的情况下就地完成。考虑postgresql.org/support/versioning
【解决方案3】:

3。 我认为最快的方法是:

select regexp_replace(
  'And more food or drinks at the international airport Ltd',
  '[[:<:]](and|or|Ltd|international)[[:>:]]',
  ' ',
  'gi'
);

这会返回:

 more food  drinks at the  airport

我假设Ltd. 确实是Ltd,因为在第一个答案中过滤掉了一个点。

【讨论】:

    猜你喜欢
    • 2021-02-16
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多