2009-02-01 21 views
5

me gustaría dividir la cadena ejemplo:¿Cómo dividir usando un carácter de prefijo usando expresiones regulares?

~ Peter ~ Lois ~ Chris ~ Meg ~ Stewie

en el carácter ~ y tienen el resultado sea

Peter
Lois
Chris
Meg
St ewie

Utilizando una función estándar de división de cadenas en javascript o C#, el primer resultado es, por supuesto, una cadena vacía. Me gustaría evitar tener que ignorar el primer resultado porque el primer resultado puede ser una cadena vacía.

He estado jugueteando con el uso de una expresión regular y estoy perplejo. Estoy seguro de que alguien ha encontrado una solución elegante para esto.

+0

Er, ¿qué es lo que realmente quieres? Parece que no quiere deshacerse del primer elemento, pero quiere permitir que sea una cadena vacía ... ¿puede volver a redactar esa sección? – Rob

+0

De acuerdo, dice que quiere permitir que el primer elemento sea una cadena vacía, ¿cómo diferirá eso del caso en el que desea que el resultado comience con una cadena no vacía? –

Respuesta

4

Para modificar las preferencias, veo dos opciones:

(1) quitar el carácter inicial prefijo, si está presente.

(2) Use una expresión regular completa para separar la cadena.

Ambos se ilustran en este código:

using System; 
using System.Linq; 
using System.Text.RegularExpressions; 

class APP { static void Main() { 

string s = "~Peter~Lois~Chris~Meg~Stewie"; 

// #1 - Trim+Split 
Console.WriteLine ("[#1 - Trim+Split]"); 
string[] result = s.TrimStart('~').Split('~'); 
foreach (string t in result) { Console.WriteLine("'"+t+"'"); } 

// #2 - Regex 
Console.WriteLine ("[#2 - Regex]"); 
Regex RE = new Regex("~([^~]*)"); 
MatchCollection theMatches = RE.Matches(s); 
foreach (Match match in theMatches) { Console.WriteLine("'"+match.Groups[1].Value+"'"); } 

// #3 - Regex with LINQ [ modified from @ccook's code ] 
Console.WriteLine ("[#3 - Regex with LINQ]"); 
Regex.Matches(s, "~([^~]*)") 
    .OfType<Match>() 
    .ToList() 
    .ForEach(m => Console.WriteLine("'"+m.Groups[1].Value+"'")) 
    ; 
}} 

La expresión regular en el # 2 coincide con el carácter delimitador seguido de un grupo de fósforo que contiene cero o más caracteres no delimitadores. Las coincidencias resultantes son las cadenas delimitadas (incluidas las cadenas vacías). Para cada coincidencia, "match.Value" es toda la cadena, incluido el delimitador principal y "match.Groups 1 .Value" es el primer grupo de coincidencia que contiene la cadena libre de delimitador.

Para completar, se incluye la tercera codificación (n. ° 3) que muestra el mismo método de expresión regular en n. ° 2, pero en un estilo de codificación LINQ.

Si tiene problemas con expresiones regulares, le recomiendo Mastering Regular Expressions, Third Edition by Jeffrey E. F. Friedl. Es, de lejos, la mejor ayuda para comprender las expresiones regulares y luego sirve como una excelente referencia o actualización según sea necesario.

1

En C#, esto parece obtener lo que desea:

"~Peter~Lois~Chris~Meg~Stewie".Split("~".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
+0

.No es necesaria la llamada ToCharArray() si solo utiliza comillas simples alrededor del ~ carácter, '~' en lugar de "~" –

+0

@ spoon16: Para la sobrecarga predeterminada, eso es correcto, pero porque estoy usando la sobrecarga que toma la enumeración , Tengo que pasar una matriz real para el primer personaje. Obtuve un error de compilación sin eso. –

1

Aquí hay un enfoque LINQ ...

Nota, con RegexOptions.ExplicitCapture no se incluyen los partidos. Sin él, el '~' también se incluirá.

using System; 
using System.Linq; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string s = "~Peter~Lois~Chris~Meg~Stewie"; 
      Regex.Split(s, "(~)", RegexOptions.ExplicitCapture) 
       .Where(i=>!String.IsNullOrEmpty(i)) 
       .ToList().ForEach(i => Console.WriteLine(i)); 
      Console.ReadLine(); 
     } 
    } 
} 
+0

Desafortunadamente, esto elimina todas las cadenas vacías [similar a ".Split ('~', StringSplitOptions.RemoveEmptyEntries)" respuesta], pero el interrogador quiere cadenas internas vacías preservadas. El enfoque es esclarecedor, así que, he publicado una modificación a mi respuesta, que incluye una codificación LINQ similar. – rivy

Cuestiones relacionadas