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:]].