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