我有一个列eventDate,其中包含尾随空格。我试图用PostgreSQL函数TRIM()删除它们。更具体地说,我正在运行:
选择修剪(从eventDate开始的两个“”)
从事件日期开始;
但是,尾随空格不会消失。此外,当我尝试从日期中修剪另一个字符(例如数字)时,它也不会修剪。如果我正确阅读了手册,这应该可以。有什么想法吗
有许多不同的隐形角色。它们中的许多具有Unicode格式的属性WSpace=Y(“whitespace”)。但有些特殊字符不被考虑;空白“;并且仍然没有可见的表示。维基百科关于空格(标点符号)和空白字符的优秀文章应该会让你有所了解
<;咆哮>;Unicode在这方面很糟糕:引入了大量的外来字符,这些字符主要会让人感到困惑。</咆哮>
默认情况下,标准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
手册:
在括号表达式中,括在括号中的字符类的名称
[:和:]表示属于该角色的所有字符的列表
类。标准字符类名称为:alnum,alpha,blank,cntrl,
数字,图形,下部,打印,点,空间,上部,xdigit。
这些代表ctype中定义的字符类。
一个地区可以提供其他地区。
我的
还要注意Postgres 10中固定的这一限制:
修复正则表达式对大字符的字符类处理
代码,尤其是U+7FF上面的Unicode字符(Tom Lane)以前,这些字符从未被识别为属于
依赖于区域设置的字符类,如[[:alpha:]