Saltar al contenido

Recorte los espacios finales con PostgreSQL

Luis, parte de este staff, nos hizo el favor de crear este post ya que controla muy bien el tema.

Solución:

Hay muchos personajes invisibles diferentes. Muchos de ellos tienen la propiedad WSpace=Y (“espacio en blanco”) en Unicode. Pero algunos caracteres especiales no se consideran “espacios en blanco” y aún no tienen representación visible. Los excelentes artículos de Wikipedia sobre el espacio (puntuación) y los espacios en blanco deberían darte una idea.

Unicode apesta en este sentido: introducir muchos personajes exóticos que sirven principalmente para confundir a la gente.

El SQL estándar trim() La función por defecto solo recorta el carácter de espacio latino básico (Unicode: U + 0020 / ASCII 32). Lo mismo con el rtrim() y ltrim() variantes. Su llamada también solo se dirige a ese personaje en particular.

Usa expresiones regulares con regexp_replace() en lugar de.

Trailing

Para eliminar todo arrastrando espacio en blanco (pero no espacios en blanco dentro los string):

SELECT regexp_replace(eventdate, 's+$', '') FROM eventdates;

La expresión regular explicó:
s .. clase de expresión regular taquigrafía para [[:space:]]

– que es el conjunto de caracteres de espacio en blanco – consulte las limitaciones a continuación
+ .. 1 o más partidos consecutivos
$ .. final de string

Manifestación:

SELECT regexp_replace('inner white   ', 's+$', '') || '|'

Devoluciones:

inner white|

Si, eso es un soltero barra invertida). Detalles en esta respuesta relacionada.

  • SQL seleccione donde la columna comienza con

Principal

Para eliminar todos los espacios en blanco principales (pero no espacios en blanco dentro del string):

regexp_replace(eventdate, '^s+', '')

^ .. inicio de string

Ambos

Para eliminar ambos, puede encadenar las llamadas a funciones anteriores:

regexp_replace(regexp_replace(eventdate, '^s+', ''), 's+$', '')

O puede combinar ambos en una sola llamada con dos sucursales.
Agregar 'g' como cuarto parámetro para reemplazar todas las coincidencias, no solo el primero:

regexp_replace(eventdate, '^s+|s+$', '', 'g')

Pero eso normalmente debería ser más rápido con substring():

substring(eventdate, 'S(?:.*S)*')

S .. todo pero espacio en blanco
(?:re) Conjunto de paréntesis que no captura
.* .. alguna string de 0-n caracteres

O uno de estos:

substring(eventdate, '^s*(.*S)')
substring(eventdate, '(S.*S)')

(re) .. Capturando un conjunto de paréntesis

Toma efectivamente el primer carácter que no sea un espacio en blanco y todo hasta el último carácter que no sea un espacio en blanco, si está disponible.

Espacio en blanco?

Hay algunos caracteres más relacionados que no están clasificados como “espacios en blanco” en Unicode, por lo que no están incluidos en la clase de caracteres. [[:space:]].

Estos se imprimen como glifos invisibles en pgAdmin para mí: “vocal de mongolia”, “espacio de ancho cero”, “no ensamblador de ancho cero”, “ensamblador de ancho cero”:

SELECT E'u180e', E'u200B', E'u200C', E'u200D';

'᠎' | '​' | '‌' | '‍'

Dos más, imprimiendo como visible glifos en pgAdmin, pero invisibles en mi navegador: “unión de palabras”, “espacio sin ruptura de ancho cero”:

SELECT E'u2060', E'uFEFF';
'⁠' | ''

En última instancia, si los caracteres se vuelven invisibles o no, también depende de la fuente utilizada para la visualización.

Para eliminar todos estos también, reemplace 's' con '[su180eu200Bu200Cu200Du2060uFEFF]' o '[s᠎​‌‍⁠]' (¡tenga en cuenta los caracteres invisibles que se arrastran!).
Ejemplo, en lugar de:

regexp_replace(eventdate, 's+$', '')

usar:

regexp_replace(eventdate, '[su180eu200Bu200Cu200Du2060uFEFF]+$', '')

o:

regexp_replace(eventdate, '[s᠎​‌‍⁠]+$', '')  -- note invisible characters

Limitaciones

También existe la clase de caracteres Posix. [[:graph:]] se supone que representa “caracteres visibles”. Ejemplo:

substring(eventdate, '([[:graph:]].*[[:graph:]])')

Funciona de manera confiable para caracteres ASCII en cada configuración (donde se reduce a [x21-x7E]), pero más allá de eso, actualmente (incluida la página 10) depende de la información proporcionada por el sistema operativo subyacente (para definir ctype) y posiblemente la configuración regional.

Estrictamente hablando, ese es el caso de cada referencia a una clase de personaje, pero parece haber más desacuerdo con los menos utilizados como grafico. Pero es posible que tengas que agregar más personajes a la clase de personaje. [[:space:]] (taquigrafía s) para capturar todos los caracteres de espacio en blanco. Igual que: u2007, u202f y u00a0 parece que también falta para @XiCoN JFS.

El manual:

Dentro de una expresión entre corchetes, el nombre de una clase de caracteres entre
[: and :] representa la lista de todos los personajes que pertenecen a esa clase. Los nombres de las clases de caracteres estándar son: alnum, alpha, blank, cntrl,
digit, graph, lower, print, punct, space, upper, xdigit. Estos representan el clases de caracteres definidas en ctype. Un lugar puede proporcionar otros.

El énfasis audaz es mío.

También tenga en cuenta esta limitación que se corrigió con Postgres 10:

Se corrigió el manejo de clases de caracteres de las expresiones regulares para códigos de caracteres grandes, particularmente los caracteres Unicode anteriores U+7FF (Tom Lane)

Anteriormente, estos caracteres nunca se reconocían como pertenecientes a clases de caracteres dependientes de la configuración regional, como [[:alpha:]].

Debería funcionar de la forma en que lo está manejando, pero es difícil de decir sin conocer el string.

Si solo está recortando los espacios iniciales, es posible que desee utilizar la forma más concisa:

SELECT RTRIM(eventDate) 
FROM EventDates;

Esta es una pequeña prueba para demostrarle que funciona. ¡Dinos si funciona!

Si su espacio en blanco es más que el space valor meta del que necesitará usar regexp_replace:

 SELECT '(' || REGEXP_REPLACE(eventDate, E'[[:space:]]', '', 'g') || ')' 
 FROM EventDates;

En el ejemplo anterior, estoy delimitando el valor de retorno en ( y ) solo para que puedas fácilmente ver que el reemplazo de expresiones regulares está funcionando en un indicador psql. Entonces querrás eliminarlos en tu código.

Eres capaz de animar nuestro estudio añadiendo un comentario o dejando una valoración te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *