Има много различни невидими герои. Много от тях имат свойството WSpace=Y („прабел“) в Unicode. Но някои специални знаци не се считат за "прабел" и все още нямат видимо представяне. Отличните статии в Уикипедия за интервал (пунктуация) и бели символи трябва да ви дадат представа.
Стандартният SQL trim() функцията по подразбиране отрязва само основния символ на латински интервал (Unicode:U+0020 / ASCII 32). Същото с rtrim() и ltrim() варианти. Вашето обаждане също е насочено само към този конкретен знак.
Използвайте регулярни изрази с regexp_replace() вместо това.
Завършване
За да премахнете всички крайни бели интервали (но не и бяло пространство вътре низа):
SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;
Регулярният израз е обяснен:\s ... съкращаване на класа на регулярни изрази за [[:space:]]
- което е набор от знаци за интервал - вижте ограниченията по-долу + ... 1 или повече последователни съвпадения$ ... край на низ
Демо:
SELECT regexp_replace('inner white ', '\s+$', '') || '|'
Връща:
inner white|
Да, това е единично обратна наклонена черта (\ ). Подробности в този свързан отговор:
- SQL изберете къде колоната започва с \
Водеща
За да премахнете всички водещи бели интервали (но не празно пространство вътре в низа):
regexp_replace(eventdate, '^\s+', '')
^ .. начало на низ
И двете
За да премахнете и двете , можете да верижите по-горе извиквания на функции:
regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')
Или можете да комбинирате и двете в едно обаждане с два клона .
Добавете 'g' като 4-ти параметър за замяна на всички съвпадения, а не само на първия:
regexp_replace(eventdate, '^\s+|\s+$', '', 'g')
Но това обикновено трябва да е по-бързо с substring() :
substring(eventdate, '\S(?:.*\S)*')
\S ... всичко освен бяло пространство(?: re ) ... неулавящ набор от скоби.* ... всеки низ от 0-n знака
Или едно от тези:
substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)') -- only works for 2+ printing characters
( re ) ... Заснемане на набор от скоби
Ефективно приема първия знак без интервал и всичко до последния знак без интервал, ако е наличен.
Пространство?
Има още няколко свързани знака, които не са класифицирани като "бели интервали" в Unicode - така че не се съдържат в символния клас [[:space:]] .
Те се отпечатват като невидими глифове в pgAdmin за мен:"монголска гласна", "пространство с нула ширина", "несъединяване с нулева ширина", "дограма с нула ширина":
SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';
'' | '' | '' | ''
Още две, отпечатване като видимо глифове в pgAdmin, но невидими в моя браузър:"word joiner", "zero width non-breaking space":
SELECT E'\u2060', E'\uFEFF';
'' | ''
В крайна сметка, дали знаците ще бъдат изобразени невидими или не, също зависи от шрифта, използван за показване.
За да премахнетевсички тези също така заменете '\s' с '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]' или '[\s]' (обърнете внимание на невидимите знаци в края!).
Пример, вместо:
regexp_replace(eventdate, '\s+$', '')
използвайте:
regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')
или:
regexp_replace(eventdate, '[\s]+$', '') -- note invisible characters
Ограничения
Съществува и класът на символите Posix [[:graph:]] трябва да представлява "видими знаци". Пример:
substring(eventdate, '([[:graph:]].*[[:graph:]])')
Работи надеждно за 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(Том Лейн)Преди това такива знаци никога не са били разпознавани като принадлежащи на зависими от локал класове знаци, като
[[:alpha:]].