PowerShell – Comment supprimer les accents et les caractères spéciaux ?

I. Présentation

Dans ce tutoriel, nous allons voir comment supprimer les accents et les caractères spéciaux dans une chaîne (string) au sein d'un script PowerShell.

Quand on fait du scripting et que l'on manipule des noms et des prénoms, on se retrouve rapidement face aux caractères accentués et aux caractères spéciaux. Si l'on veut s'appuyer sur un nom et un prénom pour générer un identifiant de connexion, il est préférable d'éliminer tous les accents. Comment faire ? Je vais vous expliquer comment procéder en PowerShell.

II. PowerShell et -replace

Pour commencer, nous allons voir une méthode basique qui s'appuie sur l'utilisation de -replace. Il s'agit d'une méthode qui va permettre de remplacer une chaîne de caractères par une autre. Ainsi, on peut remplacer "é" par "e", "à" par "a", "ç" par "c", etc.

Prenons un exemple :

"Prénom" -replace "é","e"

Ce qui donne :

On peut voir que cela fonctionne bien, mais que ça permet de gérer seulement le caractère "é". Si l'on gérer d'autres caractères, il faut cumuler plusieurs -replace :

"Prénom" -replace "é","e" -replace "è","e" -replace "à","a"

C'est un peu long et on risque d'en oublier, mais ça fonctionne ! Cela fonctionne aussi pour les caractères spéciaux, pour remplacer un tiret, un underscore voire même pour supprimer un espace !

Nous pourrions créer une fonction qui permettrait de supprimer tous les caractères spéciaux d'une chaîne envoyée entrée, comme ceci :

Function Remove-StringSpecialCharacters
{

   Param([string]$String)

   $String -replace 'é', 'e' `
           -replace 'è', 'e' `
           -replace 'ç', 'c' `
           -replace 'ë', 'e' `
           -replace 'à', 'a' `
           -replace 'ö', 'o' `
           -replace 'ô', 'o' `
           -replace 'ü', 'u' `
           -replace 'ï', 'i' `
           -replace 'î', 'i' `
           -replace 'â', 'a' `
           -replace 'ê', 'e' `
           -replace 'û', 'u' `
           -replace '-', '' `
           -replace ' ', '' `
           -replace '/', '' `
           -replace '\*', '' `
           -replace "'", "" 
}

Ensuite, pour appeler cette fonction il suffit de faire :

Remove-StringSpecialCharacters -String "éèà ï-ö"

On peut voir que la valeur retournée est :

eeaio

Le résultat est propre puisque les caractères spéciaux et accentués sont éliminés. Mais, nous allons voir que l'on peut faire mieux enfin disons plus efficace et plus simple. Cette méthode est intéressant pour créer une fonction qui va remplacer ou supprimer certains types de caractères, à votre guise !

Avant d'aller plus loin, je souhaitais attirer votre attention sur cette ligne :

-replace '\*', '' `

Elle va permettre de remplacer le caractère "*" (et non "\*") par rien. On doit spécifier "\" devant "*" pour faire un échappement car sinon -replace va l'interpréter comme une expression régulière.

III. PowerShell : créer une fonction pour supprimer les caractères accentués et spéciaux

En jouant sur l'encodage de la chaîne de caractères, on peut transformer une chaîne accentuée en chaîne non accentuée, facilement. A condition de connaître la syntaxe, que j'ai pu découvrir ici.

En utilisant la ligne ci-dessous, on peut remplacer l'intégralité des caractères accentués par leur équivalent non accentués.

[Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes("Prénom"))

C'est vraiment redoutable car cela fonctionne très bien ! Par contre, il faut savoir que cela n'élimine pas les espaces, ni les tirets, etc.... Sauf que ce sont des caractères courants et que l'on peut avoir envie de supprimer. Pour vous dire, j'ai déjà vu des exports CSV avec des noms et prénoms qui contiennent un "*" à la fin. Il faut s'attendre à tout et l'anticiper dans le script....

En reprenant cette ligne de base, on va pouvoir améliorer notre fonction précédente :

function Remove-StringSpecialCharacters
{
   param ([string]$String)

   Begin{}

   Process {

      $String = [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String))

      $String = $String -replace '-', '' `
                        -replace ' ', '' `
                        -replace '/', '' `
                        -replace '\*', '' `
                        -replace "'", "" 
   }

   End{
      return $String
      }
}

Dans l'exemple ci-dessus, nous allons supprimer certains caractères spéciaux. Libre à vous d'en ajouter ou d'en supprimer afin d'obtenir une chaîne de caractères toute propre !

Au niveau de la syntaxe, on peut faire plus court :

function Remove-StringSpecialCharacters
{
   param ([string]$String)

   [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String)) `
      -replace '-', '' `
      -replace ' ', '' `
      -replace '/', '' `
      -replace '\*', '' `
      -replace "'", "" 
}

Vous n'avez plus qu'à intégrer cette fonction dans votre script et à l'utiliser ! 😉

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian BURNEL

Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

Nombre de posts de cet auteur : 5575.Voir tous les posts

One thought on “PowerShell – Comment supprimer les accents et les caractères spéciaux ?

  • function Remove-StringDiacritic
    {

    [CMdletBinding()]
    PARAM
    (
    [ValidateNotNullOrEmpty()]
    [Alias(‘Text’)]
    [System.String[]]$String,
    [System.Text.NormalizationForm]$NormalizationForm = « FormD »
    )

    FOREACH ($StringValue in $String)
    {
    Write-Verbose -Message « $StringValue »
    try
    {
    # Normalize the String
    $Normalized = $StringValue.Normalize($NormalizationForm)
    $NewString = New-Object -TypeName System.Text.StringBuilder

    # Convert the String to CharArray
    $normalized.ToCharArray() |
    ForEach-Object -Process {
    if ([Globalization.CharUnicodeInfo]::GetUnicodeCategory($psitem) -ne [Globalization.UnicodeCategory]::NonSpacingMark)
    {
    [void]$NewString.Append($psitem)
    }
    }

    #Combine the new string chars
    Write-Output $($NewString -as [string])
    }
    Catch
    {
    Write-Error -Message $Error[0].Exception.Message
    }
    }
    }

    Répondre

Répondre à David ALTAE Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.