PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Pangkas spasi tambahan dengan PostgreSQL

Ada banyak karakter tak terlihat yang berbeda. Banyak dari mereka memiliki properti WSpace=Y ("spasi") di Unicode. Tetapi beberapa karakter khusus tidak dianggap "spasi putih" dan masih tidak memiliki representasi yang terlihat. Artikel Wikipedia yang sangat bagus tentang spasi (tanda baca) dan karakter spasi akan memberi Anda gambaran.

Unicode payah dalam hal ini:memperkenalkan banyak karakter eksotik yang biasanya membingungkan orang.

SQL standar trim() fungsi secara default hanya memangkas karakter spasi Latin dasar (Unicode:U+0020 / ASCII 32). Sama dengan rtrim() dan ltrim() varian. Panggilan Anda juga hanya menargetkan karakter tertentu.

Gunakan ekspresi reguler dengan regexp_replace() sebagai gantinya.

Mengikuti

Untuk menghapus semua spasi kosong yang tertinggal (tetapi bukan spasi di dalam string):

SELECT regexp_replace(eventdate, '\s+$', '') FROM eventdates;

Ekspresi reguler menjelaskan:
\s ... singkatan kelas ekspresi reguler untuk [[:space:]]
    - yang merupakan kumpulan karakter spasi putih - lihat batasan di bawah
+ ... 1 atau lebih pertandingan berturut-turut
$ ... akhir string

Demo:

SELECT regexp_replace('inner white   ', '\s+$', '') || '|'

Pengembalian:

inner white|

Ya, itu adalah tunggal garis miring terbalik (\ ). Detail dalam jawaban terkait ini:

  • SQL pilih di mana kolom dimulai dengan

Terkemuka

Untuk menghapus semua spasi kosong (tetapi bukan spasi putih di dalam string):

regexp_replace(eventdate, '^\s+', '')

^ .. awal string

Keduanya

Untuk menghapus keduanya , Anda dapat menyambungkan panggilan fungsi di atas:

regexp_replace(regexp_replace(eventdate, '^\s+', ''), '\s+$', '')

Atau Anda dapat menggabungkan keduanya dalam satu panggilan dengan dua cabang .
Tambahkan 'g' sebagai parameter ke-4 untuk menggantikan semua kecocokan, bukan hanya yang pertama:

regexp_replace(eventdate, '^\s+|\s+$', '', 'g')

Tapi itu biasanya lebih cepat dengan substring() :

substring(eventdate, '\S(?:.*\S)*')

\S ... semuanya tetapi spasi
(?: re ) ... kumpulan tanda kurung yang tidak digunakan
.* ... string apa pun dengan karakter 0-n

Atau salah satu dari ini:

substring(eventdate, '^\s*(.*\S)')
substring(eventdate, '(\S.*\S)')  -- only works for 2+ printing characters

( re ) ... Menangkap set tanda kurung

Secara efektif mengambil karakter non-spasi pertama dan semuanya hingga karakter non-spasi terakhir jika tersedia.

Spasi putih?

Ada beberapa karakter terkait lainnya yang tidak diklasifikasikan sebagai "spasi putih" di Unicode - jadi tidak termasuk dalam kelas karakter [[:space:]] .

Ini dicetak sebagai mesin terbang tak terlihat di pgAdmin untuk saya:"vokal mongolia", "spasi lebar nol", "non-penggabung lebar nol", "penggabung lebar nol":

SELECT E'\u180e', E'\u200B', E'\u200C', E'\u200D';

'᠎' | '​' | '‌' | '‍'

Dua lagi, mencetak sebagai terlihat mesin terbang di pgAdmin, tetapi tidak terlihat di browser saya:"penggabung kata", "ruang tanpa batas lebar nol":

SELECT E'\u2060', E'\uFEFF';
'⁠' | ''

Pada akhirnya, apakah karakter menjadi tidak terlihat atau tidak juga bergantung pada font yang digunakan untuk tampilan.

Untuk menghapus semua ini juga, ganti '\s' dengan '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]' atau '[\s᠎​‌‍⁠]' (perhatikan karakter tambahan yang tidak terlihat!).
Contoh, sebagai ganti:

regexp_replace(eventdate, '\s+$', '')

gunakan:

regexp_replace(eventdate, '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]+$', '')

atau:

regexp_replace(eventdate, '[\s᠎​‌‍⁠]+$', '')  -- note invisible characters

Batasan

Ada juga kelas karakter Posix [[:graph:]] seharusnya mewakili "karakter yang terlihat". Contoh:

substring(eventdate, '([[:graph:]].*[[:graph:]])')

Ini bekerja dengan andal untuk karakter ASCII di setiap pengaturan (di mana intinya adalah [\x21-\x7E] ), tetapi di luar itu saat ini Anda (termasuk. hal 10) bergantung pada informasi yang diberikan oleh OS yang mendasarinya (untuk menentukan ctype ) dan mungkin pengaturan lokal.

Sebenarnya, itulah yang terjadi pada setiap referensi ke kelas karakter, tetapi tampaknya ada lebih banyak ketidaksepakatan dengan yang kurang umum digunakan seperti grafik . Tetapi Anda mungkin harus menambahkan lebih banyak karakter ke kelas karakter [[:space:]] (singkatan \s ) untuk menangkap semua karakter spasi. Seperti:\u2007 , \u202f dan \u00a0 tampaknya juga hilang untuk @XiCoN JFS.

Panduan:

Dalam ekspresi kurung, nama kelas karakter diapit di[: dan :] singkatan dari daftar semua karakter yang termasuk dalam kelas itu. Nama kelas karakter standar adalah:alnum , alpha , blank , cntrl ,digit , graph , lower , print , punct , space , upper , xdigit .Ini singkatan dari kelas karakter yang didefinisikan dalam ctype.Lokal dapat menyediakan yang lain.

Penekanan saya yang berani.

Perhatikan juga batasan ini yang diperbaiki dengan Postgres 10:

Perbaiki penanganan kelas karakter ekspresi reguler untuk kode karakter besar, terutama karakter Unicode di atas U+7FF (Tom Lane)

Sebelumnya, karakter seperti itu tidak pernah dikenali sebagai milik kelas karakter yang bergantung pada lokal seperti [[:alpha:]] .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lokasi default database PostgreSQL di Linux

  2. SQL - Menggabungkan beberapa kueri serupa

  3. Kolom PostgreSQL tidak ada tetapi sebenarnya ada

  4. Izin ditolak saat mencoba mengimpor file CSV dari PGAdmin

  5. Kesalahan postgres saat memasukkan - KESALAHAN:urutan byte tidak valid untuk penyandian UTF8:0x00