Menanyakan baris non-ASCII dari Postgres


14

Apakah [:ascii:]kelas berfungsi di Postgres? Itu tidak tercantum dalam bantuan mereka , namun saya melihat contoh di web yang menggunakannya.

Saya memiliki database UTF-8, di mana collation dan c_typ e berada en_US.UTF-8, dan versi Postgres adalah 9.6.2. Ketika saya mencari baris non-ASCII seperti ini:

select title from wallabag_entry where title ~ '[^[:ascii:]]';

Saya mendapatkan kedua Unicode dan non-Unicode simbol (output penuh adalah di sini ):

Сталинская правозащитница: мать Меленкова бабушка Настя
Дневник НКВДиста Шабалина: Знает ли Москва положение на фронте?
Бег по городу и поездка на осле: как в средневековье наказывали прелюбодеев
Как комиссар Крекшин в 1740 чуть не отменил историю России
Have you heard of Saint Death? Dont pray to her.
Архаїчна українська мова: перевага чи недолік?
Гренада не их
Chinas marriage rate is plummeting because women are choosing autonomy over 

Apa yang salah dengan permintaan ini?


1
Apakah mungkin Anda mendapatkan kalimat dengan ruang Unicode yang tidak dapat dipecahkan? (atau karakter lain apa pun yang bersembunyi di tampilan biasa)
joanolo

@ Joanolo, bagaimana cara memeriksa ini? Bagaimana cara melihat tampilan yang tidak jelas?
Suncatcher

Anda dapat menggunakan a regexp_replace()untuk menandai karakter non-ASCII Anda. Lihat jawaban saya.
joanolo

1
Anda harus selalu menempelkan hasil pastinya di dba.se. Kami tidak dapat menguji grafik untuk karakter non-ascii. kita dapat menguji set hasil yang sebenarnya. Ini adalah poster anak yang seharusnya tidak menjadi grafik
Evan Carroll

2
Hanya untuk menambahkan dua sen saya: sementara jawaban joanolo sangat spektakuler, itu tidak membantu saya untuk memecahkan masalah konkret ini. Kecuali kutipan yang tepat, dataset saya memiliki banyak karakter membingungkan lainnya (seperti spasi, ",«) yang membuatnya tidak mungkin menggunakan [:ascii:]kelas. Apa yang benar-benar membantu saya dalam masalah ini adalah konsep blok unicode, yang saya pelajari dari regex hebat ini tutorial .
Suncatcher

Jawaban:


25

Untuk menjawab pertanyaan Anda: [:ascii:]berfungsi. Anda mungkin memiliki beberapa karakter dalam teks yang tidak Anda kenal sebagai non-ASCII , namun mereka ada di sana. Mereka dapat berupa ruang yang tidak dapat dipecahkan , misalnya, atau karakter ruang Unicode lainnya .

Tidak aneh untuk memiliki spasi yang tidak dapat dipecahkan (  ) dalam teks yang Anda salin dan tempel dari halaman web, namun Anda tidak melihat mereka ada di sana.

Ini adalah contoh untuk ditampilkan:

WITH t(t) AS
(
    VALUES 
      ( 'Сталинская правозащитница: мать Меленкова бабушка Настя' ),
      ( 'Дневник НКВДиста Шабалина: Знает ли Москва положение на фронте?' ),
      ( 'Бег по городу и поездка на осле: как в средневековье наказывали прелюбодеев' ),
      ( 'Как комиссар Крекшин в 1740-е чуть не отменил историю России' ),
      ( 'Have you heard of Saint Death? Don’t pray to her.' ),
      ( 'Архаїчна українська мова: перевага чи недолік?' ),
      ( 'Гренада не их' ),
      ( 'China’s marriage rate is plummeting because women are choosing autonomy over ' )

)
SELECT 
    t,  regexp_replace(t, '([^[:ascii:]])', '[\1]', 'g') AS t_marked
FROM 
    t 
WHERE 
    t ~ '[^[:ascii:]]' ;

Itu Apa yang Anda Dapatkan:

                                       t                                       |                                                                                                 t_marked                                                                                                  
-------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Сталинская правозащитница: мать Меленкова бабушка Настя                       | [С][т][а][л][и][н][с][к][а][я] [п][р][а][в][о][з][а][щ][и][т][н][и][ц][а]: [м][а][т][ь] [М][е][л][е][н][к][о][в][а] [б][а][б][у][ш][к][а] [Н][а][с][т][я]
 Дневник НКВДиста Шабалина: Знает ли Москва положение на фронте?               | [Д][н][е][в][н][и][к] [Н][К][В][Д][и][с][т][а] [Ш][а][б][а][л][и][н][а]: [З][н][а][е][т] [л][и] [М][о][с][к][в][а] [п][о][л][о][ж][е][н][и][е] [н][а] [ф][р][о][н][т][е]?
 Бег по городу и поездка на осле: как в средневековье наказывали прелюбодеев   | [Б][е][г] [п][о] [г][о][р][о][д][у] [и] [п][о][е][з][д][к][а] [н][а] [о][с][л][е]: [к][а][к] [в] [с][р][е][д][н][е][в][е][к][о][в][ь][е] [н][а][к][а][з][ы][в][а][л][и] [п][р][е][л][ю][б][о][д][е][е][в]
 Как комиссар Крекшин в 1740 чуть не отменил историю России                  | [К][а][к] [к][о][м][и][с][с][а][р] [К][р][е][к][ш][и][н] [в] 1740-[е] [ч][у][т][ь] [н][е] [о][т][м][е][н][и][л] [и][с][т][о][р][и][ю] [Р][о][с][с][и][и]
 Have you heard of Saint Death? Dont pray to her.                             | Have you heard of Saint Death? Don[’]t pray to her.
 Архаїчна українська мова: перевага чи недолік?                                | [А][р][х][а][ї][ч][н][а] [у][к][р][а][ї][н][с][ь][к][а] [м][о][в][а]: [п][е][р][е][в][а][г][а] [ч][и] [н][е][д][о][л][і][к]?
 Гренада не их                                                                 | [Г][р][е][н][а][д][а] [н][е] [и][х]
 Chinas marriage rate is plummeting because women are choosing autonomy over  | China[’]s marriage rate is plummeting because women are choosing autonomy over 

Anda dapat melihat dari sini, bahwa masalah Anda adalah karakter apostrof yang tepat . ASCII hanya mendukung tanda kutip. Apostrof kiri dan apostrof kanan adalah ekstensi Unicode yang benar secara tipografis.

Aku di sini

Anda dapat memeriksanya juga dengan versi sebelumnya di http://rextester.com/UKIQ48014 (PostgreSQL 9.5) dan http://sqlfiddle.com/#!15/4c563/1/0 (PostgreSQL 9.3)


Teks-teks yang saya kira menurut Anda adalah ASCII murni, dan bukan :

 WITH t(t) AS
 (
     VALUES 
       ('A fully ASCII text!'),
       ('Have you heard of Saint Death? Don’t pray to her.'),
       ('China’s marriage rate is plummeting because women are choosing autonomy over ')
 )
 SELECT 
    regexp_replace(t, '([^[:ascii:]])', '[\1]', 'g') AS t_marked
 FROM 
    t 
 WHERE 
    t ~ '[^[:ascii:]]' ;
| t_marked |
 | : ------------------------------------------------- ----------------------------- |
 | Pernahkah Anda mendengar tentang Saint Death? Jangan [berdoa] padanya. |
 | Tingkat perkawinan China menurun karena perempuan lebih memilih otonomi |
 

Aku di sini

Teks-teks ini menggunakan ' bukan ' untuk menandai apostrof.

Periksa Tanda Baca: Mengapa kutipan tunggal yang tepat (U + 2019), dan bukan tanda kutip yang berbeda secara semantik (U + 0027), karakter tanda kutip yang disukai dalam Unicode? ... untuk memastikan bahwa Anda bukan orang pertama yang menghadapi masalah ini.


3
Ini adalah jawaban yang sangat fantastis karena menunjukkan kepada Anda karakter non-ascii. Ini adalah bagaimana saya akan menjawab pertanyaan ini.
Evan Carroll

1
Saya memperbarui dengan contoh OPs.
Evan Carroll

1
Jawaban yang benar-benar fantastis dan bermanfaat! Terima kasih.
Suncatcher
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.