Abfragen von Nicht-ASCII-Zeilen aus Postgres

14

Funktioniert der [:ascii:]Unterricht überhaupt in Postgres? Es ist nicht in ihrer Hilfe aufgeführt , ich sehe jedoch Beispiele im Web , die es verwenden.

Ich habe eine UTF-8 - Datenbank, in der Zusammenstellung und c_typ e sind en_US.UTF-8, und Postgres Version ist 9.6.2. Wenn ich nach Nicht-ASCII-Zeilen wie folgt suche:

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

Ich erhalte sowohl Unicode- als auch Nicht-Unicode-Symbole (die vollständige Ausgabe ist hier ):

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

Was ist los mit dieser Abfrage?

Sonnenfänger
quelle
1
Ist es möglich, dass Sie Sätze mit nicht unterbrechbaren Unicode-Leerzeichen erhalten? (oder ein anderes Zeichen, das sich im Klartext verbirgt)
joanolo
@joanolo, wie kann ich das überprüfen? Wie sieht man nicht-einfache Ansicht?
Suncatcher
Sie können a verwenden regexp_replace(), um Ihre Nicht-ASCII-Zeichen zu markieren. Siehe meine Antwort.
Joanolo
1
Sie sollten immer das genaue Ergebnis in dba.se einfügen. Wir können keine Grafik auf Nicht-ASCII-Zeichen testen. Wir können die tatsächliche Ergebnismenge testen. Dies ist ein Aushängeschild für sollte keine Grafik sein
Evan Carroll
2
Um nur zwei Cent hinzuzufügen: Die Antwort von joanolo ist zwar spektakulär, hat mir aber nicht geholfen, dieses konkrete Problem zu lösen. Abgesehen von richtigen Anführungszeichen enthält mein Datensatz eine Reihe anderer verwirrender Zeichen (Leerzeichen, ",«), die es [:ascii:]sowieso unmöglich machen, Klasse zu verwenden. Was mir bei diesem Problem wirklich geholfen hat, ist ein Konzept von Unicode-Blöcken, das ich aus dieser fabelhaften Regex gelernt habe Tutorial .
Suncatcher

Antworten:

25

Um Ihre Frage zu beantworten: [:ascii:]funktioniert. Sie können einige Zeichen in Ihrem Text haben , dass Sie nicht so erkennen Nicht-ASCII , aber sie sind da. Sie können beispielsweise ein nicht aufbrechbares Leerzeichen oder ein beliebiges anderes Unicode-Leerzeichen sein .

Es ist nicht ungewöhnlich, dass Texte, die Sie aus einer Webseite kopieren und einfügen, nicht zerbrechliche Leerzeichen (  ) enthalten. Sie bemerken jedoch nicht, dass sie vorhanden sind.

Hier ist ein Beispiel zu zeigen:

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

Das ist, was du bekommst:

                                       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 

Daran können Sie erkennen, dass es sich bei Ihrem Problem um das Zeichen mit dem rechten Apostroph handelt . ASCII unterstützt nur den Apostroph. Links- und Rechtsapostroph sind typografisch korrekte Unicode-Erweiterungen.

dbfiddle hier

Sie können dies auch mit früheren Versionen unter http://rextester.com/UKIQ48014 (PostgreSQL 9.5) und http://sqlfiddle.com/#!15/4c563/1/0 (PostgreSQL 9.3) überprüfen.


Die Texte, von denen ich glaube, dass Sie sie für reines ASCII halten, sind nicht :

 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_markiert |
 | : ------------------------------------------------- ----------------------------- |
 | Hast du von Saint Death gehört? Bete nicht zu ihr. |
 | Chinas Heiratsquote sinkt, weil Frauen Autonomie vorziehen
 

dbfiddle hier

In diesen Texten werden Apostrophe mit " anstelle von " markiert.

Überprüfen Zeichensetzung: Warum ist die richtige Apostroph (U + 2019) und nicht die semantisch unterschiedliche Apostroph (U + 0027), die bevorzugte Apostroph in Unicode? ... um zu sehen, dass Sie nicht die erste Person sind, die auf dieses Problem stößt.

joanolo
quelle
3
Dies ist eine wirklich fantastische Antwort, da sie Ihnen die Nicht-ASCII-Zeichen zeigt. So hätte ich diese Frage beantwortet.
Evan Carroll
1
Ich habe mit dem OPs Beispiel aktualisiert.
Evan Carroll
1
Wirklich fantastische und hilfreiche Antwort! Vielen Dank.
Suncatcher