Istnieje wiele różnych niewidzialnych postaci. Wiele z nich ma właściwość WSpace=Y
(„białe znaki”) w Unicode. Ale niektóre znaki specjalne nie są uważane za „białe znaki” i nadal nie mają widocznej reprezentacji. Świetne artykuły Wikipedii dotyczące spacji (interpunkcji) i białych znaków powinny dać ci pomysł.
Standardowy SQL trim()
funkcja domyślnie przycina tylko podstawowy znak spacji łacińskiej (Unicode:U+0020 / ASCII 32). To samo z rtrim()
i ltrim()
warianty. Twoje wezwanie jest również kierowane tylko na tę konkretną postać.
Używaj wyrażeń regularnych z regexp_replace()
zamiast tego.
Kontynuacja
Aby usunąć wszystkie końcowe białe znaki (ale nie spacja wewnątrz ciąg):
SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;
Wyjaśnienie wyrażenia regularnego:\s
... skrót klasy wyrażenia regularnego dla [[:space:]]
- czyli zestaw znaków odstępu – zobacz ograniczenia poniżej +
... 1 lub więcej kolejnych dopasowań$
... koniec ciągu
Demo:
SELECT regexp_replace('inner white ', '\s+$', '') || '|'
Zwroty:
inner white|
Tak, to singiel ukośnik odwrotny (\
). Szczegóły w tej powiązanej odpowiedzi:
- SQL wybierz, gdzie kolumna zaczyna się od \
Wiodący
Aby usunąć wszystkie wiodące białe znaki (ale nie spacja wewnątrz ciągu):
regexp_replace(eventdate, '^\s+', '')
^
.. początek ciągu
Oba
Aby usunąć oba , możesz połączyć powyższe wywołania funkcji:
regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')
Możesz też połączyć oba w jednym połączeniu z dwoma oddziałami .
Dodaj 'g'
jako czwarty parametr zastępujący wszystkie dopasowania, nie tylko pierwszy:
regexp_replace(eventdate, '^\s+|\s+$', '', 'g')
Ale zazwyczaj powinno to być szybsze dzięki substring()
:
substring(eventdate, '\S(?:.*\S)*')
\S
... wszystko ale spacja(?:
re
)
... nieprzechwytujący zestaw nawiasów.*
... dowolny ciąg 0-n znaków
Lub jedno z tych:
substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)') -- only works for 2+ printing characters
(
re
)
... Przechwytywanie zestawu nawiasów
Skutecznie pobiera pierwszy znak inny niż biały i wszystko aż do ostatniego znaku innego niż biały, jeśli jest dostępny.
białe znaki?
Istnieje kilka innych powiązanych znaków, które nie są klasyfikowane jako "białe znaki" w Unicode - więc nie są zawarte w klasie znaków [[:space:]]
.
Dla mnie są one drukowane jako niewidoczne glify w pgAdmin:"mongolska samogłoska", "spacja o zerowej szerokości", "bez łączenia o zerowej szerokości", "łącznik o zerowej szerokości":
SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';
'' | '' | '' | ''
Jeszcze dwa, drukowanie jako widoczne glify w pgAdmin, ale niewidoczne w mojej przeglądarce:"word joiner", "zero szerokości nierozdzielającej spacji":
SELECT E'\u2060', E'\uFEFF';
'' | ''
Ostatecznie to, czy znaki są renderowane jako niewidoczne, czy nie, zależy również od czcionki użytej do wyświetlania.
Aby usunąć wszystkie te również zastąp '\s'
z '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]'
lub '[\s]'
(zwróć uwagę na końcowe niewidoczne znaki!).
Przykład zamiast:
regexp_replace(eventdate, '\s+$', '')
użyj:
regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')
lub:
regexp_replace(eventdate, '[\s]+$', '') -- note invisible characters
Ograniczenia
Istnieje również klasa znaków Posix [[:graph:]]
ma reprezentować „widoczne postacie”. Przykład:
substring(eventdate, '([[:graph:]].*[[:graph:]])')
Działa niezawodnie dla znaków ASCII w każdej konfiguracji (gdzie sprowadza się do [\x21-\x7E]
), ale poza tym obecnie (w tym str. 10) polegasz na informacjach dostarczanych przez bazowy system operacyjny (aby zdefiniować ctype
) i ewentualnie ustawienia regionalne.
Ściśle mówiąc, dotyczy to każdego odniesienie do klasy znaków, ale wydaje się, że istnieje więcej niezgodności z mniej powszechnie używanymi, takimi jak graph . Ale być może będziesz musiał dodać więcej znaków do klasy znaków [[:space:]]
(skrót \s
), aby wychwycić wszystkie białe znaki. Na przykład:\u2007
, \u202f
i \u00a0
wydaje się, że brakuje również dla @XiCoN JFS.
Instrukcja:
W wyrażeniu nawiasu klamrowego nazwa klasy znaku zawarta w [:
i :]
oznacza listę wszystkich postaci należących do tej klasy. Standardowe nazwy klas postaci to:alnum
, alpha
, blank
, cntrl
,digit
, graph
, lower
, print
, punct
, space
, upper
, xdigit
.Oznaczają one klasy znaków zdefiniowane w ctype.Lokale mogą zapewnić inne.
Pogrubiony nacisk na moje.
Zwróć również uwagę na to ograniczenie, które zostało naprawione w Postgres 10:
Napraw obsługę klas znaków wyrażeń regularnych dla dużych kodów znaków, szczególnie znaków Unicode powyżej U+7FF
(Tom Lane)
Wcześniej takie znaki nigdy nie były rozpoznawane jako należące do klas znaków zależnych od lokalizacji, takich jak [[:alpha:]]
.