PowerShell Advanced — Topic #3

Remove Accents and Special Characters

Remover acentos y caracteres especiales

Prepare names for legacy systems that do not support accented or special Latin characters by converting values such as García, Muñoz, and Peña into clean compatible text.

Preparar nombres para sistemas antiguos que no soportan acentos o caracteres latinos especiales, convirtiendo valores como García, Muñoz y Peña en texto limpio y compatible.

FocusEnfoque
Legacy compatibilityCompatibilidad legacy
ToolHerramienta
PowerShell + Unicode Normalization + Regex
OutputResultado
Accent-free valuesValores sin acentos

Cybersecurity & Production Environment Warning

Advertencia de ciberseguridad y ambiente de producción

This exercise is for learning and testing purposes only. Do not run scripts against production data, network shares, official HR files, student records, patient records, enterprise repositories, or business-critical folders without proper authorization, backups, testing, least-privilege permissions, change-control approval, and compliance with your organization’s cybersecurity policies.

Este ejercicio es solo para aprendizaje y pruebas. No ejecutes scripts contra datos de producción, carpetas compartidas, archivos oficiales de recursos humanos, expedientes de estudiantes, expedientes de pacientes, repositorios empresariales o carpetas críticas sin autorización, respaldos, pruebas, permisos mínimos, aprobación de control de cambios y cumplimiento de las políticas de ciberseguridad de tu organización.

Business Scenario

Escenario de negocio

A CSV file contains last names with accents and special characters. A downstream legacy system only accepts basic Latin characters. The goal is to remove diacritics while preserving the readable meaning of the name as much as possible.

Un archivo CSV contiene apellidos con acentos y caracteres especiales. Un sistema antiguo solo acepta caracteres latinos básicos. El objetivo es remover marcas diacríticas preservando lo más posible el significado legible del nombre.

García → GarciaMuñoz → MunozPeña → PenaÁlvarez → Alvarez

Learning Objectives

Objetivos de aprendizaje

Sample Input Data

Data de entrada de ejemplo

EmployeeID,Nombre,Apellido
1001,José,García
1002,María,Muñoz
1003,Ana,Peña
1004,Ángel,López
1005,Zoë,Nuñez

Step 1 — Define Source and Output Files

Paso 1 — Definir archivos de entrada y salida

$sourceFile = "C:\Training\names_raw.csv"
$outputFile = "C:\Training\names_clean.csv"

Step 2 — Import the CSV File

Paso 2 — Importar el archivo CSV

$records = Import-Csv -Path $sourceFile

Step 3 — Create a Function to Remove Accents

Paso 3 — Crear una función para remover acentos

The function below separates letters from accent marks using Unicode FormD, then removes the marks using the regex category \p{M}.

La función siguiente separa las letras de las marcas de acento usando Unicode FormD, y luego remueve esas marcas usando la categoría regex \p{M}.

function Remove-Accents {
    param(
        [string]$Text
    )

    if ([string]::IsNullOrWhiteSpace($Text)) {
        return $Text
    }

    $normalized = $Text.Normalize([System.Text.NormalizationForm]::FormD)
    $cleanText = $normalized -replace '\p{M}', ''

    return $cleanText
}

Step 4 — Clean Name Fields

Paso 4 — Limpiar campos de nombre

Apply the function to selected fields. In this example, both first name and last name are cleaned.

Aplicamos la función a los campos seleccionados. En este ejemplo, se limpian el nombre y el apellido.

$records | ForEach-Object {
    $_.Nombre = Remove-Accents $_.Nombre
    $_.Apellido = Remove-Accents $_.Apellido
}

Step 5 — Optional: Remove Unsupported Special Characters

Paso 5 — Opcional: remover caracteres especiales no soportados

Some legacy systems only accept letters, numbers, spaces, apostrophes, and hyphens. This optional step removes anything outside that allowed pattern.

Algunos sistemas antiguos solo aceptan letras, números, espacios, apóstrofes y guiones. Este paso opcional remueve cualquier cosa fuera de ese patrón permitido.

$records | ForEach-Object {
    $_.Nombre = $_.Nombre -replace "[^a-zA-Z0-9 '\-]", ''
    $_.Apellido = $_.Apellido -replace "[^a-zA-Z0-9 '\-]", ''
}

Step 6 — Export the Clean File

Paso 6 — Exportar el archivo limpio

$records | Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8

Complete Script

Script completo

$sourceFile = "C:\Training\names_raw.csv"
$outputFile = "C:\Training\names_clean.csv"

function Remove-Accents {
    param(
        [string]$Text
    )

    if ([string]::IsNullOrWhiteSpace($Text)) {
        return $Text
    }

    $normalized = $Text.Normalize([System.Text.NormalizationForm]::FormD)
    $cleanText = $normalized -replace '\p{M}', ''

    return $cleanText
}

$records = Import-Csv -Path $sourceFile

$records | ForEach-Object {
    $_.Nombre = Remove-Accents $_.Nombre
    $_.Apellido = Remove-Accents $_.Apellido

    # Optional legacy cleanup
    $_.Nombre = $_.Nombre -replace "[^a-zA-Z0-9 '\-]", ''
    $_.Apellido = $_.Apellido -replace "[^a-zA-Z0-9 '\-]", ''
}

$records | Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8

Expected Result

Resultado esperado

Before

Antes

NombreApellido
JoséGarcía
MaríaMuñoz
AnaPeña
ÁngelLópez
ZoëNuñez

After

Después

NombreApellido
JoseGarcia
MariaMunoz
AnaPena
AngelLopez
ZoeNunez

Validation Checklist

Lista de validación

Professional Notes

Notas profesionales

Removing accents should be treated as a compatibility transformation, not as an identity correction. In official records, legal names should remain exactly as provided unless the business process explicitly requires a legacy-compatible export.

Remover acentos debe tratarse como una transformación de compatibilidad, no como una corrección de identidad. En registros oficiales, los nombres legales deben mantenerse exactamente como fueron provistos, salvo que el proceso requiera explícitamente una exportación compatible con sistemas antiguos.