2009-02-01 12 views
5

Vorrei dividere la stringa esempio:Come dividere usando un carattere prefisso usando le espressioni regolari?

~ Peter ~ Lois ~ Chris ~ Meg ~ Stewie

sul carattere ~ ed avere il risultato sia

Peter
Lois
Chris
Meg
St ewie

Utilizzando una funzione di divisione stringa standard in javascript o C# il primo risultato è ovviamente una stringa vuota. Vorrei evitare di dover ignorare il primo risultato perché il primo risultato potrebbe essere effettivamente una stringa vuota.

Sono stato in giro con l'uso di un'espressione regolare e sono perplesso. Sono sicuro che qualcuno ha trovato una soluzione elegante a questo.

+0

Ehm, che cosa vuoi veramente? Sembra che tu voglia non abbandonare il primo elemento, ma vuoi permettere che sia una stringa vuota ... puoi riformulare quella sezione? – Rob

+0

D'accordo, dici di voler consentire al primo elemento di essere una stringa vuota, in che modo questo differisce dal caso in cui vuoi che il risultato inizi con una stringa non vuota? –

risposta

4

Per le tue esigenze, vedo due opzioni:

(1) Rimuovere il carattere iniziale prefisso, se presente.

(2) Utilizzare un'espressione regolare completa per separare la stringa.

Entrambi sono illustrati in questo codice:

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+"'")) 
    ; 
}} 

L'espressione regolare a # 2 corrisponde al carattere delimitatore seguito da un gruppo corrispondenza contenente zero o più caratteri non delimitatore. Le corrispondenze risultanti sono le stringhe delimitate (comprese eventuali stringhe vuote). Per ogni corrispondenza, "match.Value" è l'intera stringa includendo il delimitatore principale e "match.Groups 1 .Value" è il primo gruppo di corrispondenza contenente la stringa libera delimitatore.

Per completezza, è inclusa la terza codifica (n. 3) che mostra lo stesso metodo di espressione regolare in # 2, ma in uno stile di codifica LINQ.

Se si ha difficoltà con le espressioni regolari, consiglio vivamente lo Mastering Regular Expressions, Third Edition by Jeffrey E. F. Friedl. È di gran lunga il miglior aiuto per comprendere le espressioni regolari e in seguito serve come riferimento o aggiornamento eccellente, se necessario.

1

In C#, questo sembra per ottenere ciò che si vuole:

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

.La chiamata a ToCharArray() non è necessaria se si usano solo virgolette singole attorno al carattere ~, '~' invece di "~" –

+0

@ spoon16: per il sovraccarico predefinito, è corretto, ma poiché sto utilizzando il sovraccarico che richiede l'enumerazione , Devo passare un array reale per il primo personaggio. Ho ottenuto un errore di compilazione senza di esso. –

1

Ecco un approccio LINQ ...

nota, con RegexOptions.ExplicitCapture le partite non sono inclusi. Senza di esso verrà incluso anche il '~'.

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

Sfortunatamente, questo rimuove tutte le stringhe vuote [simile alla "risposta .Split ('~', StringSplitOptions.RemoveEmptyEntries)", ma l'interrogante vuole conservare le stringhe vuote interne. L'approccio è illuminante, quindi, ho pubblicato una modifica alla mia risposta, inclusa una codifica LINQ simile. – rivy

Problemi correlati