web-dev-qa-db-fra.com

PostgreSQL regexp_replace () pour ne garder qu'un seul espace

Je dois nettoyer une colonne de chaîne avec à la fois des espaces et des tabulations, au début ou à la fin des chaînes (c'est un gâchis!). Je veux garder juste un espace entre chaque mot. Disons que nous avons la chaîne suivante qui inclut toutes les situations possibles:

mystring = '  one two    three      four    '
  • 2 espaces blancs avant "un" 
  • 1 espace entre "un" et "deux" 
  • 4 espaces blancs entre "deux" et "trois" 
  • 2 onglets après 'trois' 
  • 1 onglet après 'quatre' 

Voici comment je le fais:

  1. Je supprime les espaces de début et de fin
  2. Je supprime les onglets de début et de fin
  3. Je remplace les deux "espaces blancs répétés au moins deux" et les onglets par un seul espace blanc

WITH

  t1 AS (SELECT'  one two    three      four    '::TEXT AS mystring),

  t2 AS (SELECT TRIM(both ' ' from mystring) AS mystring FROM t1),

  t3 AS (SELECT TRIM(both '\t' from mystring) AS mystring FROM t2)

  SELECT regexp_replace(mystring, '(( ){2,}|\t+)', ' ', 'g') FROM t3 ;

J'obtiens finalement la chaîne suivante, qui a l'air bien mais j'ai toujours un espace de fuite ...

'one two three four '

Une idée sur le faire d'une manière plus simple et résoudre ce dernier problème?

Merci beaucoup !

16
wiltomap
SELECT trim(regexp_replace(col_name, '\s+', ' ', 'g')) as col_name FROM table_name;

Ou en cas de mise à jour:

UPDATE table_name SET col_name = trim(regexp_replace(col_name, '\s+', ' ', 'g'));
28
augustorf

SELECT trim(regexp_replace(mystring, '\s+', ' ', 'g')) as mystring FROM t1;

Publier une réponse au cas où les gens ne regarderaient pas les commentaires.

Utilisez '\s+'

Pas '\\s+'

Travaillé pour moi.

1
openwonk

Cela n'a pas fonctionné pour moi avec trim et regexp_replace. Alors je suis venu avec une autre solution:

SELECT trim(
    array_to_string(
        regexp_split_to_array('  test    with many  spaces  for        this   test  ', E'\\s+')
    , ' ')
) as mystring;

First regexp_split_to_array élimine tous les espaces en laissant des "espaces" au début et à la fin.

-- regexp_split_to_array output:
-- {"",test,with,many,spaces,for,this,test,""}

Quand using array_to_string tous les ',' deviennent des espaces

-- regexp_split_to_array output ( '_' instead of spaces for viewing ):
-- _test_with_many_spaces_for_this_test_

La garniture est d'enlever la tête et la queue

-- trim output ( '_' instead of spaces for viewing ):
-- test_with_many_spaces_for_this_test
0
Dan