Interrogation de lignes non ASCII à partir de Postgres

14

La [:ascii:]classe fonctionne- t - elle à Postgres? Il n'est pas répertorié dans leur aide , mais je vois des exemples sur le Web qui l'utilisent.

J'ai une base de données UTF-8, où le classement et c_typ e sont en_US.UTF-8, et la version Postgres est 9.6.2. Lorsque je recherche des lignes non ASCII comme celle-ci:

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

Je reçois les deux symboles Unicode et non Unicode (sortie complète est ici ):

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

Quel est le problème avec cette requête?

Suncatcher
la source
1
Est-il possible que vous obteniez des phrases avec des espaces incassables Unicode? (ou tout autre personnage qui se cache bien en vue, d'ailleurs)
joanolo
@joanolo, comment vérifier cela? Comment voir une vue pas simple?
Suncatcher
Vous pouvez utiliser un regexp_replace()pour marquer vos caractères non ASCII. Voir ma réponse.
joanolo
1
Vous devez toujours coller le résultat exact dans dba.se. Nous ne pouvons pas tester un graphique pour les caractères non ascii. nous pouvons tester l'ensemble de résultats réel. Ceci est une affiche enfant pour ne devrait pas être un graphique
Evan Carroll
2
Juste pour ajouter mes deux cents: bien que la réponse de joanolo soit spectaculaire, cela ne m'a pas aidé à résoudre ce problème concret. Sauf les bonnes citations, mon jeu de données contient un tas d'autres caractères déroutants (espaces similaires, ","), ce qui rend de toute façon impossible l'utilisation de la [:ascii:]classe. Ce qui m'a vraiment aidé dans ce problème est un concept de blocs unicode, que j'ai appris de cette fabuleuse expression régulière tutoriel .
Suncatcher

Réponses:

25

Pour répondre à votre question: [:ascii:]ça marche. Vous pouvez avoir des caractères dans votre texte que vous ne reconnaissez pas comme non-ASCII , mais ils sont là. Ils peuvent être quelque chose comme un espace insécable , par exemple, ou tout autre caractère d'espace Unicode .

Il n'est pas étrange d'avoir des espaces insécables (  ) dans les textes que vous copiez et collez à partir d'une page Web, mais vous ne remarquez pas qu'ils sont là.

Voici un exemple à montrer:

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

C'est ce que tu as:

                                       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 

Vous pouvez voir de cela que votre problème est le caractère d'apostrophe droite . ASCII ne prend en charge que l'apostrophe. L'apostrophe gauche et l'apostrophe droite sont des extensions Unicode typographiquement correctes.

dbfiddle ici

Vous pouvez également le vérifier avec les versions précédentes sur http://rextester.com/UKIQ48014 (PostgreSQL 9.5) et http://sqlfiddle.com/#!15/4c563/1/0 (PostgreSQL 9.3)


Les textes que je pense que vous pensez sont purement ASCII, et ne le sont pas :

 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 |
 | : ------------------------------------------------- ----------------------------- |
 | Avez-vous entendu parler de Saint Death? Ne la priez pas. |
 | Le taux de mariage en Chine [est] en chute libre parce que les femmes préfèrent l'autonomie à |
 

dbfiddle ici

Ces textes utilisent « au lieu de » pour marquer les apostrophes.

Vérifiez la ponctuation: pourquoi la bonne citation unique (U + 2019), et non l'apostrophe sémantiquement distincte (U + 0027), le caractère d'apostrophe préféré dans Unicode? ... pour voir que vous n'êtes pas la première personne à rencontrer ce problème.

joanolo
la source
3
C'est une réponse vraiment fantastique car elle vous montre les caractères non-ascii. C'est ainsi que j'aurais répondu à cette question.
Evan Carroll
1
J'ai mis à jour avec l'exemple OPs.
Evan Carroll
1
Réponse vraiment fantastique et utile! Merci.
Suncatcher