Existem muitos personagens invisíveis diferentes. Muitos deles têm a propriedade
WSpace=Y
("espaço em branco") em Unicode. Mas alguns caracteres especiais não são considerados "espaços em branco" e ainda não possuem representação visível. Os excelentes artigos da Wikipedia sobre espaço (pontuação) e caracteres de espaço em branco devem dar uma ideia. O padrão SQL
trim()
a função por padrão apenas apara o caractere de espaço latino básico (Unicode:U+0020 / ASCII 32). O mesmo com o rtrim()
e ltrim()
variantes. Sua chamada também visa apenas esse personagem em particular. Use expressões regulares com
regexp_replace()
em vez de. À direita
Para remover todos os espaços em branco à direita (mas não espaço em branco dentro a corda):
SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;
A expressão regular explicada:
\s
... abreviação de classe de expressão regular para [[:space:]]
- que é o conjunto de caracteres de espaço em branco - veja as limitações abaixo
+
... 1 ou mais correspondências consecutivas$
... fim da corda Demonstração:
SELECT regexp_replace('inner white ', '\s+$', '') || '|'
Devoluções:
inner white|
Sim, é um único barra invertida (
\
). Detalhes nesta resposta relacionada:- SQL seleciona onde a coluna começa com \
Liderando
Para remover todos os espaços em branco à esquerda (mas não espaço em branco dentro da string):
regexp_replace(eventdate, '^\s+', '')
^
.. início da string Ambos
Para remover ambos , você pode encadear as chamadas de função acima:
regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')
Ou você pode combinar ambos em uma única chamada com duas ramificações .
Adicionar
'g'
como 4º parâmetro para substituir todas as correspondências, não apenas a primeira:regexp_replace(eventdate, '^\s+|\s+$', '', 'g')
Mas isso normalmente deve ser mais rápido com
substring()
:substring(eventdate, '\S(?:.*\S)*')
\S
... tudo mas espaço em branco(?:
re
)
... conjunto de parênteses sem captura.*
... qualquer string de 0-n caracteres Ou um destes:
substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)') -- only works for 2+ printing characters
(
re
)
... Capturando conjunto de parênteses Efetivamente leva o primeiro caractere sem espaço em branco e tudo até o último caractere sem espaço em branco, se disponível.
Espaço em branco?
Existem mais alguns caracteres relacionados que não são classificados como "espaço em branco" em Unicode - portanto, não estão contidos na classe de caracteres
[[:space:]]
. Eles são impressos como glifos invisíveis no pgAdmin para mim:"vogal mongol", "espaço de largura zero", "não-juntor de largura zero", "juntor de largura zero":
SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';
'' | '' | '' | ''
Mais dois, imprimindo como visível glifos no pgAdmin, mas invisíveis no meu navegador:"word joiner", "espaço sem quebra de largura zero":
SELECT E'\u2060', E'\uFEFF';
'' | ''
Em última análise, se os caracteres são tornados invisíveis ou não, também depende da fonte usada para exibição.
Para remover todos esses também, substitua
'\s'
com '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]'
ou '[\s]'
(observe caracteres invisíveis à direita!).Exemplo, em vez de:
regexp_replace(eventdate, '\s+$', '')
usar:
regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')
ou:
regexp_replace(eventdate, '[\s]+$', '') -- note invisible characters
Limitações
Há também a classe de caracteres Posix
[[:graph:]]
supostamente para representar "caracteres visíveis". Exemplo:substring(eventdate, '([[:graph:]].*[[:graph:]])')
Funciona de forma confiável para caracteres ASCII em todas as configurações (onde se resume a
[\x21-\x7E]
), mas além disso você atualmente (incl. pág. 10) depende das informações fornecidas pelo sistema operacional subjacente (para definir ctype
) e possivelmente configurações de localidade. Estritamente falando, esse é o caso de todos referência a uma classe de caracteres, mas parece haver mais desacordo com os menos usados, como graph . Mas você pode ter que adicionar mais caracteres à classe de caracteres
[[:space:]]
(abreviação \s
) para capturar todos os caracteres de espaço em branco. Como:\u2007
, \u202f
e \u00a0
também parecem estar faltando para @XiCoN JFS. O manual:
Dentro de uma expressão de colchetes, o nome de uma classe de caracteres entre[:
e:]
representa a lista de todos os caracteres pertencentes a essa classe. Os nomes de classes de caracteres padrão são:alnum
,alpha
,blank
,cntrl
,digit
,graph
,lower
,punct
,space
,upper
,xdigit
.Eles representam as classes de caracteres definidas em ctype.Uma localidade pode fornecer outras.
Minha ênfase em negrito.
Observe também esta limitação que foi corrigida com o Postgres 10:
Corrige a manipulação de classes de caracteres de expressões regulares para códigos de caracteres grandes, particularmente caracteres Unicode acima deU+7FF
(Tom Lane)
Anteriormente, esses caracteres nunca eram reconhecidos como pertencentes a classes de caracteres dependentes de localidade, como[[:alpha:]]
.