Postgresql

從 Postgres 查詢非 ASCII 行

  • January 15, 2020

[:ascii:]類在 Postgres 中是否有效?它沒有在他們的幫助中列出,但是我在網上看到了使用它的範例。

我有一個 UTF-8 數據庫,其中collat ​​ion和c_type e 是en_US.UTF-8,Postgres 版本是 9.6.2。當我搜尋這樣的非 ASCII 行時:

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

我得到Unicode 和非 Unicode 符號(完整輸出在這裡):

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

這個查詢有什麼問題?

回答你的問題:[:ascii:]有效。您的文本中可能有一些您無法辨識為non-ASCII 的字元,但它們確實存在。例如,它們可以是不可破壞的空格,也可以是任何其他Unicode 空格字元

從網頁複製粘貼的文本中包含不可破壞的空格( )並不奇怪,但您卻沒有註意到它們的存在。 

這是一個範例:

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:]]' ;

這就是你得到的:

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

您可以從中看出,您的問題是右撇號字元。ASCII 僅支持撇號。左撇號和右撇號是印刷正確的 Unicode 擴展。

dbfiddle在這裡

您也可以在http://rextester.com/UKIQ48014 (PostgreSQL 9.5) 和http://sqlfiddle.com/#!15/4c563/1/0 (PostgreSQL 9.3)上查看以前的版本


我猜你認為的文本是純 ASCII,而不是

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:]]' ;
| 標記 |
| :------------------------------------------------------------------------------ |
| 你聽說過聖死嗎?不要[']向她祈禱。|
| 中國結婚率直線下降,因為女性選擇自主權|

dbfiddle在這裡

這些文本使用**’而不是’**來標記撇號。

檢查標點符號:為什麼正確的單引號 (U+2019),而不是語義上不同的撇號 (U+0027),是 Unicode 中的首選撇號字元?…看到你不是第一個遇到這個問題的人。

引用自:https://dba.stackexchange.com/questions/167566