9
votes

Postgres Expressions régulières et regexp_split_to_array

Dans PostgreSQL, j'ai besoin d'extraire les deux premiers mots de la valeur d'une colonne donnée. Donc, si la valeur est "Hello World Moon et Stars" ou "Hello World Moon" ou même "Bonjour World", j'ai besoin de "Hello World".

J'espérais utiliser regexp_split_to_array mais il ne semble pas que je puisse utiliser cela et accéder aux éléments renvoyés dans la même requête?

Dois-je créer une fonction pour ce que j'essaie de faire?


0 commentaires

4 Réponses :


2
votes

trouvé une réponse: xxx


0 commentaires

9
votes

Vous pouvez utiliser des expressions posixes régulières avec PostgreSQL's Substring ( ) code> : xxx pré>

ou avec une interprétation très libérale de ce qu'un mot est: p> xxx pré>

note le \ s code> (non-whitespace) au lieu de \ w code> ("Word" caractère, essentiellement alphanumérique plus un soulignement). p>

N'oubliez pas tout le Effacement citant non-sens cependant: p>

  • le E '' code> Pour dire PostgreSQL que vous utilisez EXTENDUM EXPAPING . LI>
  • et ensuite doublez les backslashes pour obtenir un seul dos arrière devant l'analyseur à cordes et dans l'analyseur d'expression régulier. LI> ul>

    Si vous souhaitez vraiment utiliser REGEXP_SPLIT_TO_ARRAY CODE> , vous pouvez alors que les problèmes de citation ci-dessus s'appliquent et je pense que vous voudriez couper les deux premiers éléments du tableau: P>

    select (regexp_split_to_array('hello world moon', E'\\s+'))[1:2];
    


7 commentaires

Vous pouvez utiliser le Dollar- Cité Syntaxe de chaîne pour éviter les backslash doubles: $$ ^ \ w + \ s + \ w + $$


@Joey Adams: Mais vous rencontrez ensuite des problèmes avec des expressions régulières qui sont ancrées à la fin. J'utilise généralement simplement la syntaxe e '' ' de sorte que je n'ai pas à vous rappeler un autre ensemble de règles de cotation.


@Mu Oui, c'est laid et presque ridicule, mais encore beaucoup plus facile imo que de s'échapper qui est imo un champ de mines - pour quelqu'un d'autre qui lisait ces commentaires, il suffit de choisir un modèle qui ne s'affronte pas avec la fin, par exemple: $ re $ ^ \ w + \ s + \ w + $$ re $


@mu Notez que Sélectionnez la sous-chaîne (E'IT \ 'S une belle journée' de E '^ \\ w + \\ s + \\ w +'); ne donne probablement pas le résultat souhaité


@Jackpdouglas: Je pense que nous sommes dangereusement proches de se battre via VI versus Emacs maintenant (pour le record: ed (1) est l'éditeur de texte standard; Ed Man! Man Ed!). Je trouve plus difficile de trouver la regex dans une pile tordue de panneaux de dollar que de délider mentalement les backslashes. En fin de compte, utilisez tout ce qui fonctionne et passez à des problèmes plus intéressants :)


@Jackpdouglas: Je pense que vous avez pensé à dire Sélectionner la sous-chaîne ('C'est une bonne journée' de E '^ \\ w + \\ s + \\ w +'); . J'ai ajouté une version \ s qui est probablement mieux.


@mu ne savait pas à propos de \ S - merci pour cela. Ne pas être en désaccord avec ce que vous dites sur quel type de citation à utiliser - qu'est-ce qui l'emportez pour moi sont les moments où j'ai dû échapper à mes escapades! Chevaux pour les cours comme vous le dites. PS, tu peux m'appeler @jack :-)



1
votes
select substring(my_text from $$^\s*\S+\s+\S+$$) from v;

3 commentaires

Je préfère toujours le regexp_split_to_array (texte, e '\\ s +')) [1: 2] approche, qui semble correspondre mieux à l'intention que de gâcher avec sous-chaîne et Quel "mot" est.


@Mu je serais préoccupé par la taille de mon système lorsque les cordes sont longues. Il n'y a aucune raison de supposer de la question qu'il n'y a pas de dizaines de milliers de mots sur le terrain


Assez vrai. Difficile de dire quelle est la meilleure approche serait sans plus de détails et, plus important encore, d'expérimentation sur des données réelles. J'ai tendance à commencer par la clarté et une expression directe de mon intention; Si cela ne suffit pas, alors il est temps d'être intelligents et de cycle.



17
votes

Je ne peux pas croire que 5 ans il y a 5 ans et personne remarquée que vous pouvez accéder aux éléments de regeexp_split_to_array fonction si vous les entourez avec des parenthèses.

J'ai vu beaucoup de gens ont essayé d'accéder aux éléments de la table comme ceci: xxx

Le précédent renvoie une erreur, mais ce qui suit ne sera pas le cas: xxx


1 commentaires

Note très importante! J'ai passé quelques heures avec Googling ceci. Le problème est que regexp_split_to_array () et regexp_matches () donne le résultat en tant que tableau même que la Regexp renvoie une seule chaîne uniquement.