1
votes

Qu'est-ce que l'équivalent regexp_replace dans SQL Server

J'ai ce morceau de code dans Oracle que je dois convertir en SQL Server pour obtenir le même comportement. J'ai utilisé la fonction REPLACE . Cela semble fonctionner mais je voulais juste m'en assurer.

REGEXP_REPLACE(
                phonenumber, 
               '([[:digit:]]{3})([[:digit:]]{3})([[:digit:]]{4})', 
               '(\1)\2-\3'
               ) phonenumber


5 commentaires

La fonction REPLACE dans SQL Server ne fonctionnera certainement pas pour cela


@MartinSmith des suggestions


Vous recherchez donc des chaînes correspondant exactement à 10 chiffres et essayez de les convertir en (012)345-6789 ?


Si vous avez besoin d'une prise en charge réelle de REGEX dans SQL Server, vous devez implémenter des fonctions CLR.


Oui c'est correct. donc fondamentalement, par exemple, j'ai le numéro de téléphone xxx- xxx xxxx et je voulais le formater comme (xxx) xxx- xxxx


3 Réponses :


1
votes

2 commentaires

Toujours CLR? Désormais, lorsque nous prenons en charge Java / R / Python "Ceci étend la surface TSQL pour mieux gérer les cas d'utilisation impliquant des expressions régulières, la gestion des chaînes et le support NLP."


oui, c'est vrai, CLR / Other Language Extension - toujours rien de disponible sans avoir à écrire du code personnalisé et potentiellement activer des fonctionnalités supplémentaires qui sont actuellement désactivées



0
votes

Vous pouvez écrire une fonction SQL en utilisant CLR, qui encapsulera l'expression régulière dotnet standard. J'ai écrit ceci et vous pouvez l'utiliser là-bas . Il ressemblera à ceci:

DECLARE @SourceText NVARCHAR(MAX) = N'My first line <br /> My second line';
DECLARE @RegexPattern NVARCHAR(MAX) = N'([<]br\s*/[>])';
DECLARE @Replacement NVARCHAR(MAX) = N''
DECLARE @IsCaseSensitive BIT = 0;

SELECT regex.Replace(@SourceText, @RegexPattern, @Replacement, @IsCaseSensitive);


1 commentaires

Considérant que le lien est vers un dépôt Github "Scrappy CoCo", vous devriez noter que vous l'avez écrit.



0
votes

Comme Martin l'a dit dans sa réponse , SQL Server n'a pas de fonctionnalité RegEx intégrée (et bien qu'il n'en ait pas a été suggéré ici, juste pour être clair: non, le caractère générique [...] de LIKE et PATINDEX n'est pas em> RegEx). Si vos données présentent peu ou pas de variation, alors oui, vous pouvez utiliser une combinaison de fonctions T-SQL: REPLACE , SUBSTRING , LEFT , DROIT , CHARINDEX , PATINDEX , FORMATMESSAGE , CONCAT , et peut-être un ou deux autres .

Cependant, si les données / entrées ont même un niveau de complexité modéré, alors les fonctions T-SQL intégrées seront au mieux encombrantes et au pire inutiles. Dans de tels cas, il est possible de faire du RegEx réel via SQLCLR (tant que vous n'utilisez pas Azure SQL Database Single DB ou SQL Server 2017+ via AWS RDS), qui est un code .NET (restreint) exécuté dans SQL Server. Vous pouvez coder votre propre / trouver des exemples ici sur S.O. ou ailleurs, ou essayez une bibliothèque prédéfinie telle que celle que j'ai créée, SQL # (SQLsharp) a >, dont la version gratuite contient plusieurs fonctions RegEx. Veuillez noter que SQLCLR, étant .NET, n'est pas un RegEx basé sur POSIX et n'utilise donc pas Classes de caractères POSIX (ce qui signifie: vous devrez utiliser \ d pour "chiffres" au lieu de [: digit:] ).

Le niveau de complexité nécessaire dans cette situation particulière n'est pas clair car l'exemple de code de la question implique que les données sont simples et uniformes (c'est-à-dire 1112223333 ) mais les exemples de données présentés dans un commentaire sur la question semble indiquer qu'il peut y avoir des tirets et / ou des espaces dans les données (c'est-à-dire xxx- xxx xxxx ).

Si les données sont vraiment uniformes, alors tenez-vous-en à la solution T-SQL pure fournie par @MartinSmith. Mais, si les données sont d'une complexité suffisante, veuillez considérer l'exemple RegEx ci-dessous, en utilisant une fonction SQLCLR trouvée dans la version gratuite de mon bibliothèque SQL # (comme mentionné précédemment), qui gère facilement les 3 variations de données d'entrée et plus:

(888)555-1212
(123)456-7890
(777)555-4653

renvoie:

SELECT SQL#.RegEx_Replace4k(tmp.phone,
                            N'\(?(\d{3})\)?[ .-]*(\d{3})[ .-]*(\d{4})', N'($1)$2-$3',
                            -1,   -- count (-1 == unlimited)
                            1,    -- start at
                            N'')  -- RegEx options
FROM   (VALUES (N'8885551212'),
               (N'123- 456 7890'),
               (N'(777) 555- 4653')
       ) tmp([phone]);

Le modèle RegEx permet:

  • 0 ou 1 (
  • 3 chiffres décimaux
  • 0 ou 1 )
  • 0 ou plus de , . ou -
  • 3 chiffres décimaux
  • 0 ou plus de , . ou -
  • 4 chiffres décimaux

Il a été mentionné que les nouvelles extensions de langage pourraient être un meilleur choix que SQLCLR. Les extensions de langage permettent d'appeler du code R / Python / Java, hébergé en dehors de SQL Server, via la procédure stockée sp_execute_external_script . En tant que Didacticiel: recherchez une chaîne à l'aide d'expressions régulières (regex) dans les émissions de pages Java , les scripts externes ne sont en fait pas un bon choix pour la plupart des utilisations de RegEx dans SQL Server. Les principaux problèmes sont:

  1. Contrairement à SQLCLR, la seule interface pour les scripts externes est une procédure stockée. Cela signifie que vous ne pouvez utiliser aucune de ces fonctionnalités en ligne dans une requête ( SELECT , WHERE , etc.).
  2. Avec les scripts externes, vous transmettez la requête, travaillez sur les résultats dans le langage externe et renvoyez un jeu de résultats statique. Cela signifie que le code compilé doit maintenant être plus spécialisé (c'est-à-dire étroitement couplé) à l'utilisation particulière. Changer la façon dont la requête utilise RegEx et / ou quelles colonnes sont renvoyées nécessite désormais l'édition, la compilation, le test et le déploiement du code R / Python / Java en plus ( et coordonnés avec!) Le T-SQL changements.

Je suis sûr que les scripts externes sont absolument merveilleux, et un meilleur choix que SQLCLR, dans certains scénarios. Mais ils ne se prêtent certainement pas bien à la nature très variée et souvent ad hoc de la façon dont RegEx est utilisé (comme beaucoup / la plupart des autres fonctions).


0 commentaires