Consultar filas no ASCII de Postgres

14

¿La [:ascii:]clase funciona en Postgres? No aparece en su ayuda , sin embargo, veo ejemplos en la web que lo utilizan.

Tengo una base de datos UTF-8, donde se encuentran colación y c_typ e en_US.UTF-8, y la versión de Postgres es 9.6.2. Cuando busco filas no ASCII como esta:

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

Consigo tanto Unicode y no Unicode símbolos (salida completa es aquí ):

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

¿Qué hay de malo en esta consulta?

Suncatcher
fuente
1
¿Es posible que obtenga oraciones con espacios Unicode no rompibles? (o cualquier otro personaje que se esconda a simple vista, para el caso)
joanolo
@joanolo, ¿cómo verificar esto? ¿Cómo ver una vista no simple?
Suncatcher
Puede usar a regexp_replace()para marcar sus caracteres no ASCII. Mira mi respuesta.
joanolo
1
Siempre debe pegar el resultado exacto en dba.se. No podemos probar un gráfico para caracteres no ascii. Podemos probar el conjunto de resultados real. Este es un póster para niños que no debería ser un gráfico
Evan Carroll
2
Solo para agregar mis dos centavos: aunque la respuesta de joanolo es espectacular, no me ayudó a resolver este problema concreto. Excepto las citas correctas, mi conjunto de datos tiene un montón de otros caracteres confusos (espacios iguales, ",«) lo que hace que sea imposible usar la [:ascii:]clase de todos modos. Lo que realmente me ayudó en este problema es un concepto de bloques unicode, que aprendí de esta fabulosa expresión regular tutorial .
Suncatcher

Respuestas:

25

Para responder a su pregunta: [:ascii:]funciona. Es posible que tenga algunos caracteres en su texto que no reconoce como no ASCII , pero están allí. Pueden ser algo así como un espacio no rompible , por ejemplo, o cualquier otro carácter de espacio Unicode .

No es extraño tener espacios no rompibles (  ) en los textos que copia y pega desde una página web, pero no se da cuenta de que están allí.

Aquí hay un ejemplo para mostrar:

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

Eso es lo que obtienes:

                                       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 

De esto puede ver que su problema es el carácter de apóstrofe correcto . ASCII solo es compatible con el apóstrofe. El apóstrofe izquierdo y el apóstrofe derecho son extensiones Unicode tipográficamente correctas.

dbfiddle aquí

Puede verificarlo también con versiones anteriores en http://rextester.com/UKIQ48014 (PostgreSQL 9.5) y http://sqlfiddle.com/#!15/4c563/1/0 (PostgreSQL 9.3)


Los textos que creo que crees que son ASCII puros, y no lo son :

 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:]]' ;
El | t_marked |
 El | : ------------------------------------------------- ----------------------------- |
 El | ¿Has oído hablar de Santa Muerte? No le reces a ella. El |
 El | La tasa de matrimonio de China [...] está cayendo en picada porque las mujeres eligen la autonomía sobre |
 

dbfiddle aquí

Estos textos están usando 'en lugar de ' para marcar apóstrofes.

Verifique la puntuación: ¿Por qué la comilla simple correcta (U + 2019), y no el apóstrofe semánticamente distinto (U + 0027), es el carácter de apóstrofe preferido en Unicode? ... para ver que no eres la primera persona que encuentra este problema.

joanolo
fuente
3
Esta es una respuesta realmente fantástica porque te muestra los caracteres que no son ascii. Así es como habría respondido esta pregunta.
Evan Carroll
1
Actualicé con el ejemplo de OP.
Evan Carroll
1
¡Respuesta realmente fantástica y útil! Gracias.
Suncatcher