Es gibt viele verschiedene unsichtbare Charaktere. Viele von ihnen haben die Eigenschaft WSpace=Y
("Leerzeichen") in Unicode. Einige Sonderzeichen werden jedoch nicht als "Leerzeichen" betrachtet und haben immer noch keine sichtbare Darstellung. Die hervorragenden Wikipedia-Artikel über Leerzeichen (Interpunktion) und Leerzeichen sollten Ihnen eine Vorstellung davon geben.
Das Standard-SQL trim()
-Funktion schneidet standardmäßig nur das grundlegende lateinische Leerzeichen ab (Unicode:U+0020 / ASCII 32). Dasselbe gilt für rtrim()
und ltrim()
Varianten. Ihr Anruf zielt auch nur auf diesen bestimmten Charakter ab.
Verwenden Sie reguläre Ausdrücke mit regexp_replace()
stattdessen.
Nachlaufend
Um alle nachgestellten Leerzeichen zu entfernen (aber kein Leerraum innerhalb die Zeichenkette):
SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;
Erklärung des regulären Ausdrucks:\s
... Klassenkürzel für reguläre Ausdrücke für [[:space:]]
– das ist der Satz von Leerzeichen – siehe Beschränkungen unten +
... 1 oder mehr aufeinanderfolgende Übereinstimmungen$
... Ende der Zeichenkette
Demo:
SELECT regexp_replace('inner white ', '\s+$', '') || '|'
Rückgabe:
inner white|
Ja, das ist eine Single Backslash (\
). Details in dieser verwandten Antwort:
- SQL auswählen, wo die Spalte mit \ beginnt
Führend
Um alle führenden Leerzeichen zu entfernen (aber keine Leerzeichen innerhalb der Zeichenfolge):
regexp_replace(eventdate, '^\s+', '')
^
.. Beginn der Zeichenkette
Beides
Um beide zu entfernen , können Sie die obigen Funktionsaufrufe verketten:
regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')
Oder Sie kombinieren beides in einem einzigen Aufruf mit zwei Nebenstellen .
Fügen Sie 'g'
hinzu als 4. Parameter, um alle Übereinstimmungen zu ersetzen, nicht nur die erste:
regexp_replace(eventdate, '^\s+|\s+$', '', 'g')
Aber das sollte normalerweise mit substring()
schneller gehen :
substring(eventdate, '\S(?:.*\S)*')
\S
... alles außer Leerraum(?:
re
)
... nicht erfassender Klammersatz.*
... eine beliebige Folge von 0-n Zeichen
Oder eines davon:
substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)') -- only works for 2+ printing characters
(
re
)
... Klammersatz erfassen
Nimmt effektiv das erste Nicht-Leerzeichen und alles bis zum letzten Nicht-Leerzeichen, falls verfügbar.
Leerzeichen?
Es gibt ein paar weitere verwandte Zeichen, die in Unicode nicht als "Whitespace" klassifiziert sind - also nicht in der Zeichenklasse [[:space:]]
enthalten sind .
Diese werden als unsichtbare Glyphen in pgAdmin für mich gedruckt:"mongolian vowel", "zero width space", "zero width non-joiner", "zero width joiner":
SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';
'' | '' | '' | ''
Zwei weitere, die als sichtbar gedruckt werden Glyphen in pgAdmin, aber unsichtbar in meinem Browser:"word joiner", "zero width non-breaking space":
SELECT E'\u2060', E'\uFEFF';
'' | ''
Ob Zeichen unsichtbar gemacht werden oder nicht, hängt letztendlich auch von der verwendeten Schriftart ab.
Um alle diese zu entfernen Ersetzen Sie außerdem '\s'
mit '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]'
oder '[\s]'
(Nachgestellte unsichtbare Zeichen beachten!).
Beispiel, statt:
regexp_replace(eventdate, '\s+$', '')
verwenden:
regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')
oder:
regexp_replace(eventdate, '[\s]+$', '') -- note invisible characters
Einschränkungen
Es gibt auch die Posix-Zeichenklasse [[:graph:]]
soll "sichtbare Zeichen" darstellen. Beispiel:
substring(eventdate, '([[:graph:]].*[[:graph:]])')
Es funktioniert zuverlässig für ASCII-Zeichen in jedem Setup (wobei es auf [\x21-\x7E]
hinausläuft ), aber darüber hinaus sind Sie derzeit (inkl. Seite 10) auf Informationen angewiesen, die vom zugrunde liegenden Betriebssystem bereitgestellt werden (um ctype
zu definieren ) und möglicherweise Gebietsschemaeinstellungen.
Genau genommen gilt das für jeden Verweis auf eine Zeichenklasse, aber es scheint mehr Meinungsverschiedenheiten mit den weniger gebräuchlichen wie graph zu geben . Möglicherweise müssen Sie jedoch weitere Zeichen zur Zeichenklasse [[:space:]]
hinzufügen (Kurzform \s
), um alle Leerzeichen abzufangen. Wie:\u2007
, \u202f
und \u00a0
scheinen auch für @XiCoN JFS zu fehlen.
Das Handbuch:
Innerhalb eines Klammerausdrucks der Name einer Zeichenklasse, eingeschlossen in [:
und :]
steht für die Liste aller Zeichen, die zu dieser Klasse gehören. Standard-Zeichenklassennamen sind:alnum
, alpha
, blank
, cntrl
,digit
, graph
, lower
, print
, punct
, space
, upper
, xdigit
.Diese stehen für die in ctype definierten Zeichenklassen. Ein Gebietsschema kann andere bereitstellen.
Fettdruck von mir.
Beachten Sie auch diese Einschränkung, die mit Postgres 10 behoben wurde:
Korrigieren Sie die Behandlung von Zeichenklassen regulärer Ausdrücke für große Zeichencodes, insbesondere Unicode-Zeichen über U+7FF
(Tom Lane)
Bisher wurden solche Zeichen nie als zu Gebietsschema-abhängigen Zeichenklassen wie [[:alpha:]]
erkannt .