Pregunta

Estoy escribiendo una pequeña clase para leer una lista de pares de valor clave de un archivo y escribir a un Dictionary<string, string>. Este archivo tendrá este formato:

key1:value1
key2:value2
key3:value3
...

Esto debería ser bastante fácil de hacer, pero dado que un usuario va a editar este archivo manualmente, ¿cómo debo lidiar con espacios en blanco, pestañas, saltos de línea adicionales y cosas así? Probablemente pueda usar reemplazar para eliminar los espacios en blanco y las pestañas, pero, ¿hay otros personajes "invisibles" que me falta?

O tal vez puedo eliminar todos los personajes que no son alfanuméricos ":" y los saltos de línea (ya que los saltos de línea son lo que separan un par de otro), y luego eliminar todos los saltos de línea adicionales. Si es esto, no sé cómo eliminar los personajes "All-Except algunos".

Por supuesto, también puedo verificar errores como "Key1: Value1: SomethingElse". Pero cosas así no importan mucho porque obviamente es culpa del usuario y solo mostraría un mensaje de "formato no válido". Solo quiero lidiar con las cosas básicas y luego poner todo eso en un bloque de prueba/captura en caso de que cualquier otra cosa salga mal.

Nota: No necesito ningún espacio blanco, incluso dentro de una clave o un valor.

¿Fue útil?

Solución

Los requisitos son demasiado confusos. Considerar:

"¿Cuándo es un espacio un valor? Clave?"
"¿Cuándo es un delimitador un valor? Clave?"
"¿Cuándo es una pestaña un valor? Clave?"
"¿Dónde termina un valor cuando se usa un delimitador en el contexto de un valor? Clave"?

Estos problemas darán como resultado un código lleno de una experiencia de usuario y una mala experiencia. Es por eso que tenemos reglas de idioma/gramática.

Defina una gramática simple y elimine la mayor parte de las conjeturas.

"{valor clave}",

Aquí tiene un par de clave/valor contenido en cotizaciones y separado a través de un delimitador (,). Todos los personajes extraños pueden ser ignorados. Puede usar USE XML, pero esto puede asustar a usuarios menos técnicos.

Nota, las citas son arbitrarias. Siéntase libre de reemplazar con cualquier contenedor establecido que no necesite mucho escape (solo tenga cuidado con la complejidad).

Personalmente, la concluiría en una interfaz de usuario simple y serializaría los datos como XML. Hay momentos para no hacer esto, pero no me has dado ninguna razón para no hacerlo.

Otros consejos

Hice este recientemente cuando finalmente me enojé con demasiada basura indocumentada que formaba un XML malo que estaba llegando en un feed. Efectivamente recorta cualquier cosa que no caiga entre un espacio y el ~ en la tabla ASCII:

static public string StripControlChars(this string s)
{
    return Regex.Replace(s, @"[^\x20-\x7F]", "");
}

Combinado con los otros ejemplos de regex ya publicados, deberían llevarlo a donde quiera ir.

Si usa Regex (expresiones regulares), puede filtrar todo eso con una sola función.

String newVariable Regex.replace (variable, @" s", "");

Eso eliminará espacios en blanco, chars invisibles, n y r.

Uno de los espacios "blancos" que regularmente nos muerde es el espacio no rompible. Además, nuestro sistema debe ser compatible con MS-Dynamics, que es mucho más restrictivo. Primero, creé una función que mapea los caracteres de octavo bit a su contraparte aproximada del séptimo bit, luego eliminé cualquier cosa que no estuviera en el rango X20 a X7F más limitado por la interfaz Dynamics.

Regex.Replace(s, @"[^\x20-\x7F]", "")

debería hacer ese trabajo.

var split = textLine.Split(":").Select(s => s.Trim()).ToArray();

La función TRIM () eliminará todo el espacio en blanco irrelevante. Tenga en cuenta que esto conserva el espacio en blanco dentro de una clave o valor, que puede considerar por separado.

Puedes usar string.Trim() Para eliminar los caracteres del espacio blanco:

var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = pair[0].Trim(),
                Value = pair[1].Trim(),
            };
        }).ToList();

Sin embargo, si desea eliminar todos los espacios blancos, puede usar expresiones regulares:

var whiteSpaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = whiteSpaceRegex.Replace(pair[0], string.Empty),
                Value = whiteSpaceRegex.Replace(pair[1], string.Empty),
            };
        }).ToList();

Si no tiene que ser rápido, podría usar LINQ:

string clean = new String(tainted.Where(c => 0 <= "ABCDabcd1234:\r\n".IndexOf(c)).ToArray());
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top