PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Cắt bỏ khoảng trắng ở cuối với PostgreSQL

Có nhiều nhân vật vô hình khác nhau. Nhiều người trong số họ có thuộc tính WSpace=Y ("khoảng trắng") trong Unicode. Nhưng một số ký tự đặc biệt không được coi là "khoảng trắng" và vẫn không có đại diện hiển thị. Các bài viết tuyệt vời trên Wikipedia về khoảng trắng (dấu chấm câu) và các ký tự khoảng trắng sẽ cung cấp cho bạn một ý tưởng.

Unicode tệ hại về mặt này:giới thiệu rất nhiều ký tự kỳ lạ chủ yếu gây nhầm lẫn cho mọi người.

SQL chuẩn trim() theo mặc định, chức năng chỉ cắt ký tự khoảng trắng Latinh cơ bản (Unicode:U + 0020 / ASCII 32). Tương tự với rtrim()ltrim() các biến thể. Cuộc gọi của bạn cũng chỉ nhắm mục tiêu đến ký tự cụ thể đó.

Sử dụng biểu thức chính quy với regexp_replace() thay vào đó.

Theo dõi

Để xóa tất cả khoảng trắng ở cuối (nhưng không phải khoảng trắng bên trong chuỗi):

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

Biểu thức chính quy được giải thích:
\s ... viết tắt của lớp biểu thức chính quy cho [[:space:]]
- là tập hợp các ký tự khoảng trắng - xem các giới hạn bên dưới
+ ... 1 hoặc nhiều kết quả phù hợp liên tiếp
$ ... cuối chuỗi

Demo:

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

Lợi nhuận:

inner white|

Vâng, đó là một đĩa đơn dấu gạch chéo ngược (\ ). Chi tiết trong câu trả lời liên quan này:

  • SQL chọn nơi cột bắt đầu bằng \

Dẫn đầu

Để loại bỏ tất cả khoảng trắng ở đầu (nhưng không phải khoảng trắng bên trong chuỗi):

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

^ .. đầu chuỗi

Cả hai

Để xóa cả hai , bạn có thể xâu chuỗi các lệnh gọi hàm trên:

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

Hoặc bạn có thể kết hợp cả hai trong một lệnh gọi với hai nhánh .
Thêm 'g' là tham số thứ 4 để thay thế tất cả các kết quả phù hợp, không chỉ là tham số đầu tiên:

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

Nhưng điều đó thường sẽ nhanh hơn với substring() :

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

\S ... mọi thứ nhưng khoảng trắng
(?: re ) ... tập hợp các dấu ngoặc đơn
.* ... bất kỳ chuỗi 0-n ký tự nào

Hoặc một trong những điều này:

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

( re ) ... Chụp tập hợp các dấu ngoặc đơn

Sử dụng một cách hiệu quả ký tự không có khoảng trắng đầu tiên và mọi thứ cho đến ký tự không có khoảng trắng cuối cùng nếu có.

Khoảng trắng?

Có một số ký tự liên quan khác không được phân loại là "khoảng trắng" trong Unicode - vì vậy không được chứa trong lớp ký tự [[:space:]] .

Những chữ này in dưới dạng glyph không nhìn thấy trong pgAdmin đối với tôi:"nguyên âm mông cổ", "không gian rộng bằng không", "không nối với chiều rộng bằng không", "nối bằng không có chiều rộng":

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

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

Hai nữa, in dưới dạng hiển thị glyphs trong pgAdmin, nhưng ẩn trong trình duyệt của tôi:"word joiner", "zero width non-break space":

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

Cuối cùng, việc các ký tự được hiển thị ẩn hay không cũng phụ thuộc vào phông chữ được sử dụng để hiển thị.

Để xóa tất cả những điều này cũng như thay thế '\s' với '[\s\u180e\u200B\u200C\u200D\u2060\uFEFF]' hoặc '[\s᠎​‌‍⁠]' (lưu ý các ký tự không nhìn thấy theo sau!).
Ví dụ, thay vì:

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

sử dụng:

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

hoặc:

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

Hạn chế

Ngoài ra còn có lớp ký tự Posix [[:graph:]] được cho là đại diện cho "các ký tự hiển thị". Ví dụ:

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

Nó hoạt động đáng tin cậy cho các ký tự ASCII trong mọi thiết lập (trong đó nó tổng hợp thành [\x21-\x7E] ), nhưng ngoài ra, bạn hiện tại (bao gồm trang 10) phụ thuộc vào thông tin được cung cấp bởi Hệ điều hành cơ bản (để xác định ctype ) và có thể là cài đặt ngôn ngữ.

Nói một cách chính xác, đó là trường hợp của mọi tham chiếu đến một lớp ký tự, nhưng dường như có nhiều bất đồng hơn với những lớp ít được sử dụng hơn như graph . Nhưng bạn có thể phải thêm nhiều ký tự hơn vào lớp ký tự [[:space:]] (viết tắt \s ) để bắt tất cả các ký tự khoảng trắng. Như:\u2007 , \u202f\u00a0 dường như cũng bị thiếu đối với @XiCoN JFS.

Hướng dẫn sử dụng:

Trong một biểu thức dấu ngoặc, tên của một lớp ký tự nằm trong [::] là viết tắt của danh sách tất cả các ký tự thuộc lớp đó. Tên lớp ký tự tiêu chuẩn là:alnum , alpha , blank , cntrl , digit , graph , lower , print , punct , space , upper , xdigit . Đây là viết tắt của các lớp ký tự được xác định trong ctype. Một ngôn ngữ có thể cung cấp cho các lớp khác.

Nhấn mạnh đậm của tôi.

Cũng lưu ý rằng hạn chế này đã được khắc phục với Postgres 10:

Sửa lỗi xử lý lớp ký tự của biểu thức chính quy đối với các ký tự lớn, đặc biệt là các ký tự Unicode trên U+7FF (Tom Lane)

Trước đây, các ký tự như vậy chưa bao giờ được công nhận là thuộc các lớp ký tự phụ thuộc vào ngôn ngữ, chẳng hạn như [[: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. Cách triển khai phân phối Percona cho PostgreSQL để có tính khả dụng cao

  2. Quản lý tính khả dụng cao trong PostgreSQL - Phần III:Patroni

  3. Làm cách nào để tạo bản sao lưu của một bảng trong cơ sở dữ liệu postgres?

  4. Kiểu dữ liệu Postgres JSON Truy vấn đường ray

  5. Thay đổi loại cột thành chuỗi dài hơn trong đường ray