2012-05-11 26 views
5

Ejemplo de texto (que he destacado los / deseados 's):barra diagonal excepto dentro de los corchetes

par [@ teclado = 2] Los productos // artículo [Persona/Name =' Martin'] Fecha /

Estoy tratando de obtener cada barra hacia adelante que no esté dentro de un corchete, ¿alguien con Regex capaz de ayudarme en esto? El uso sería:

string[] result = Regex.Split(text, pattern); 

lo he hecho con este código, pero me preguntaba si había una expresión regular más simple que hacer la misma cosa:

private string[] Split() 
{ 
    List<string> list = new List<string>(); 
    int pos = 0, i = 0; 
    bool within = false; 
    Func<string> add =() => Format.Substring(pos, i - pos); 
    //string a; 
    for (; i < Format.Length; i++) 
    { 
     //a = add(); 
     char c = Format[i]; 
     switch (c) 
     { 
      case '/': 
       if (!within) 
       { 
        list.Add(add()); 
        pos = i + 1; 
       } 
       break; 
      case '[': 
       within = true; 
       break; 
      case ']': 
       within = false; 
       break; 
     } 
    } 
    list.Add(add()); 
    return list.Where(s => !string.IsNullOrEmpty(s)).ToArray(); 
} 

Respuesta

2

usando Regex.Matches podría ser una mejor opción que tratar de usar split. En lugar de especificar un patrón para dividir, intenta hacer coincidir sus resultados deseados. Esto funciona en los casos básicos:

string[] FancySplit(string input) { 
    return Regex.Matches(input, @"([^/\[\]]|\[[^]]*\])+") 
     .Cast<Match>() 
     .Select(m => m.Value) 
     .ToArray(); 
} 

El enfoque de la expresión regular es la búsqueda de una secuencia de:

  • caracteres que no son [, ], o /
    o
  • Un secuencia del formulario [ algo ], donde algo está permitido contener /
2

Esto no funcionará para uso general caso, pero lo hará casos más prácticos derecha:

(?<!\[[^]]+)/ 

Esta expresión utiliza un negative lookbehind para que coincida con una barra inclinada a menos que esté precedida por un corchete seguido por una secuencia de caract otros que no sean un corchete de cierre.

+1

Para aclarar qué significa "casos prácticos" para esta respuesta, esta expresión regular funcionará siempre que no pueda "anidar" corchetes. Si puede hacer algo como esto: 'asdf [123 [456] \] jkl', entonces esta respuesta no funcionará. – Servy

+0

@Servy Tiene toda la razón: si va a permitir paréntesis de anidamiento, las soluciones basadas en expresiones regulares no serían teóricamente posibles, por la misma razón no es posible escribir una expresión regular diciendo cadenas con paréntesis equilibrados de cadenas con paréntesis desbalanceados. – dasblinkenlight

+0

Esto funciona gracias, pero puedo ir con la solución de @recursive –

Cuestiones relacionadas