使用PostgreSQL修剪尾部空格

我有一个列eventDate,其中包含尾随空格。我试图用PostgreSQL函数TRIM()删除它们。更具体地说,我正在运行:

选择修剪(从eventDate开始的两个“”)
从事件日期开始;

但是,尾随空格不会消失。此外,当我尝试从日期中修剪另一个字符(例如数字)时,它也不会修剪。如果我正确阅读了手册,这应该可以。有什么想法吗

有许多不同的隐形角色。它们中的许多具有Unicode格式的属性WSpace=Y(“whitespace”)。但有些特殊字符不被考虑;空白“;并且仍然没有可见的表示。维基百科关于空格(标点符号)和空白字符的优秀文章应该会让你有所了解

<咆哮>Unicode在这方面很糟糕:引入了大量的外来字符,这些字符主要会让人感到困惑。&lt/咆哮&gt

默认情况下,标准SQLtrim()函数仅修剪基本拉丁空格字符(Unicode:U+0020/ASCII 32)。与rtrim()ltrim()变体相同。您的呼叫也仅针对该特定角色

将正则表达式与regexp\u replace()一起使用

拖尾

要删除字符串中所有尾随的空白(但不是空白):

从eventdates中选择regexp\u replace(eventdate,“\s+$”,”);

正则表达式解释为:
\s。。。正则表达式类是[[:space:]
-这是一组空白字符-请参阅下面的限制
+。。。一个或多个连续匹配
$。。。结束

演示:

选择regexp_replace('inner white','\s+$,'')| | |'

返回:

内部白色|

是的,这是一个单反斜杠(\)。有关答案的详情如下:

  • SQL选择列以开头的位置\

领先的

要删除所有前导空格(但不是字符串中的空格),请执行以下操作:

regexp\u替换(eventdate,^\s+,“”)

^。。字符串开头

两者

要同时删除这两个函数,可以链接以上函数调用:

regexp\u replace(regexp\u replace(eventdate,“^\s+”,”,“\s+$”,”)

或者,您可以在一次调用中使用两个分支将两者结合起来
添加'g'作为第四个参数以替换所有匹配项,而不仅仅是第一个:

regexp\u替换(eventdate,^\s+\s+$,''g')

但是使用substring()通常会更快:

子字符串(eventdate,'\S(?:.*\S)*')

\S。。。一切空白
(?:re。。。非捕获括号集
*。。。任何0-n个字符的字符串

或其中一项:

子字符串(事件日期,^\s*(.*\s))
子字符串(eventdate,(\S.*\S)――仅适用于2个以上的打印字符

re。。。捕获括号集

有效地获取第一个非空白字符,以及最后一个非空白字符(如果可用)之前的所有内容

空白

还有一些相关字符未归类为;空白“;在Unicode中-因此不包含在字符类[[:space:]

这些在pgAdmin中以不可见图示符的形式为我打印:“;蒙古语元音&引用;“零宽度空间”&引用;“零宽度非连接件”&引用;“零宽度细木工”:

选择E'\u180e',E'\u200B',E'\u200C',E'\u200D';
'᠎' | '​' | '‌' | '‍'

还有两个,在pgAdmin中打印为可见的glyphs,但在我的浏览器中不可见:“;“joiner”一词&引用;零宽度非中断空间“

选择E'\u2060',E'\uFEFF';
'⁠' | ''

最终,字符是否呈现为不可见还取决于用于显示的字体

若要删除所有这些,请将'\s'替换为'[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]''[\s>᠎​‌‍⁠]'(注意尾随的不可见字符!)。
例如,而不是:

regexp\u替换(eventdate,'\s+$,'')

使用:

regexp\u replace(事件日期,[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$,“”)

或:

regexp\u替换(事件日期,[\s᠎​‌‍⁠]+$', '')  -- 注意不可见字符

局限性

还有一个Posix字符类[[:graph:]应该表示“可见字符”。示例:

子字符串(eventdate,”([[:graph:].[[:graph:]]))

它在每个设置中(归结为[\x21-\x7E])对ASCII字符都能可靠地工作,但除此之外,您当前(包括第10页)依赖于底层操作系统提供的信息(定义ctype)和可能的语言环境设置

严格地说,每个对字符类的引用都是这样,但似乎与不太常用的图形有更多的不一致。但是您可能需要向字符类添加更多字符[[:space:](缩写\s)捕获所有空白字符。例如:\u2007\u202f\u00a0似乎也缺少@XiCoN JFS

手册:

在括号表达式中,括在括号中的字符类的名称
[::]表示属于该角色的所有字符的列表
类。标准字符类名称为:alnumalphablankcntrl
数字图形下部打印空间上部xdigit
这些代表ctype中定义的字符类。
一个地区可以提供其他地区。

我的

还要注意Postgres 10中固定的这一限制:

修复正则表达式对大字符的字符类处理
代码,尤其是U+7FF上面的Unicode字符(Tom Lane)

以前,这些字符从未被识别为属于
依赖于区域设置的字符类,如[[:alpha:]

发表评论