zga*_*ll1 33 sql postgresql whitespace trim removing-whitespace
我有一个eventDate
包含尾随空格的列.我试图用PostgreSQL函数删除它们TRIM()
.更具体地说,我正在运行:
SELECT TRIM(both ' ' from eventDate)
FROM EventDates;
Run Code Online (Sandbox Code Playgroud)
然而,尾随空间不会消失.此外,当我尝试修剪日期中的另一个字符(例如数字)时,它也不会修剪.如果我正确阅读手册,这应该有效.有什么想法吗?
Erw*_*ter 61
有许多不同的隐形字符.他们中的许多人都拥有WSpace=Y
Unicode中的属性("空白").但是一些特殊字符不被视为"空白",仍然没有可见的表示.关于空间(标点符号)和空格字符的优秀维基百科文章应该会给你一个想法.
<rant> Unicode在这方面很糟糕:引入了很多充满异国情调的角色,主要是为了让人迷惑.</ rant>
trim()
默认情况下,标准SQL 函数仅修剪基本拉丁空格字符(Unicode:U + 0020/ASCII 32).同样的,在rtrim()
和ltrim()
变种.您的通话也只针对该特定角色.
regexp_replace()
改为使用正则表达式.
要删除所有尾随空格(而不是空格内的字符串):
SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;
Run Code Online (Sandbox Code Playgroud)
正则表达式解释了:
\s
正则表达式类的简写[[:space:]]
- 这是一组空白字符 - 参见下面的限制
+
..一个或多个连续匹配
$
..字符串的结尾
演示:
SELECT regexp_replace('inner white ', '\s+$', '') || '|'
Run Code Online (Sandbox Code Playgroud)
返回:
inner white|
Run Code Online (Sandbox Code Playgroud)
是的,这是一个单反斜线(\
).这个相关答案的细节.
要删除所有前导空格(但不是字符串中的空格):
regexp_replace(eventdate, '^\s+', '')
Run Code Online (Sandbox Code Playgroud)
^
..字符串的开头
要删除这两个,您可以链接上面的函数调用:
regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')
Run Code Online (Sandbox Code Playgroud)
或者,您可以在一个呼叫中将两个分支组合在一起.
添加'g'
为第4个参数来替换所有匹配,而不仅仅是第一个:
regexp_replace(eventdate, '^\s+|\s+$', '', 'g')
Run Code Online (Sandbox Code Playgroud)
但通常应该更快substring()
:
substring(eventdate, '\S(?:.*\S)*')
Run Code Online (Sandbox Code Playgroud)
\S
.. 除了空白之外的所有东西非捕获括号的集合 ..任何0-n字符的字符串
(?:
re
)
.*
或者其中一个:
substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)')
Run Code Online (Sandbox Code Playgroud)
(
re
)
.. 捕获一组括号
有效地获取第一个非空白字符以及最后一个非空白字符(如果可用).
还有一些相关的字符在Unicode中未被归类为"空白" - 因此不包含在字符类中[[:space:]]
.
这些在pgAdmin中打印为隐形字形,对我来说:"mongolian元音","零宽度空间","零宽度非连接","零宽度连接":
SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';
'?' | '?' | '?' | '?'
Run Code Online (Sandbox Code Playgroud)
另外两个,在pgAdmin中打印为可见字形,但在我的浏览器中不可见:"word joiner","零宽度不间断空格":
SELECT E'\u2060', E'\uFEFF';
'?' | ''
Run Code Online (Sandbox Code Playgroud)
最终,字符是否呈现为不可见还取决于用于显示的字体.
要删除所有这些,请替换'\s'
为'[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]'
或'[\s?????]'
(注意尾随不可见的字符!).
示例,而不是:
regexp_replace(eventdate, '\s+$', '')
Run Code Online (Sandbox Code Playgroud)
使用:
regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')
Run Code Online (Sandbox Code Playgroud)
要么:
regexp_replace(eventdate, '[\s?????]+$', '') -- note invisible characters
Run Code Online (Sandbox Code Playgroud)
还有Posix字符类[[:graph:]]
应该代表"可见字符".例:
substring(eventdate, '([[:graph:]].*[[:graph:]])')
Run Code Online (Sandbox Code Playgroud)
它可以在每个设置中可靠地处理ASCII字符(其归结为[\x21-\x7E]
),但除此之外,您当前(包括第10页)依赖于底层操作系统(定义ctype
)提供的信息以及可能的区域设置.
严格地说,对于每个对字符类的引用都是这种情况,但似乎与不太常用的字符类(例如图形)有更多不同意见.但是您可能需要在字符类[[:space:]]
(简写\s
)中添加更多字符以捕获所有空格字符.我爱:\u2007
,\u202f
并且\u00a0
似乎也失踪了@XiCoN JFS.
在括号表达式中,括在的字符类的名称
[:
和:]
代表属于该类的所有字符的列表.标准字符类的名字有:alnum
,alpha
,blank
,cntrl
,digit
,graph
,lower
,punct
,space
,upper
,xdigit
.这些代表ctype中定义的字符类.区域设置可以提供其他人.
大胆强调我的.
还要注意Postgres 10修复的这个限制:
修复正则表达式对大字符代码的字符类处理,特别是上面的Unicode字符
U+7FF
(Tom Lane)以前,这些字符从未被识别为属于依赖于语言环境的字符类,例如
[[:alpha:]]
.
它应该按照您处理它的方式工作,但是在不知道特定字符串的情况下很难说。
如果您只是修剪前导空格,您可能需要使用更简洁的形式:
SELECT RTRIM(eventDate)
FROM EventDates;
Run Code Online (Sandbox Code Playgroud)
这是一个小测试,旨在向您展示它是否有效。告诉我们是否有效!
如果您的空格不仅仅是space
元值,那么您需要使用regexp_replace
:
SELECT '(' || REGEXP_REPLACE(eventDate, E'[[:space:]]', '', 'g') || ')'
FROM EventDates;
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,我将返回值限制在(
和)
中,这样您就可以轻松地看到正则表达式替换在 psql 提示符中工作。因此,您需要删除代码中的那些内容。
归档时间: |
|
查看次数: |
48670 次 |
最近记录: |