PowerShell – Comment supprimer les accents et les caractères spéciaux ?
Sommaire
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 ! 😉
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
}
}
}