2009-12-05 23 views
31

tengo esta cadena¿Cómo dividir cadena en un diccionario

string sx="(colorIndex=3)(font.family=Helvetica)(font.bold=1)"; 

y estoy partiéndolo con

string [] ss=sx.Split(new char[] { '(', ')' }, 
    StringSplitOptions.RemoveEmptyEntries); 

En lugar de eso, ¿cómo podría dividir el resultado en un Dictionary<string,string>? El diccionario resultante debe ser similar:

Key   Value 
colorIndex 3 
font.family Helvetica 
font.bold 1 

Respuesta

17

Puede haber formas más eficientes, pero esto debería funcionar:

string sx = "(colorIndex=3)(font.family=Helvicta)(font.bold=1)"; 

var items = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries) 
    .Select(s => s.Split(new[] { '=' })); 

Dictionary<string, string> dict = new Dictionary<string, string>(); 
foreach (var item in items) 
{ 
    dict.Add(item[0], item[1]); 
} 
53

Se puede hacer uso de LINQ ToDictionary() método extensión:

string s1 = "(colorIndex=3)(font.family=Helvicta)(font.bold=1)"; 
string[] t = s1.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries); 

Dictionary<string, string> dictionary = 
         t.ToDictionary(s => s.Split('=')[0], s => s.Split('=')[1]); 

EDIT: El mismo resultado se puede lograr sin dividir twic e:

Dictionary<string, string> dictionary = 
      t.Select(item => item.Split('=')).ToDictionary(s => s[0], s => s[1]); 
+0

Ni siquiera sabía que la función de división puede tomar una matriz de cadenas como argumento. Ordenado. –

+4

¿Hay alguna forma de evitar llamar 's.Split()' dos veces? –

+13

Claro, al llamar a t.Select (item => item.Split ('=')). ToDictionary (s => s [0], s => s [1]); Similar a @erikkallen y @Luke responde. – Elisha

9
var dict = (from x in s1.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries) 
      select new { s = x.Split('=') }).ToDictionary(x => x[0], x => x[1]); 
2

usted puede hacer esto con expresiones regulares:

string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)"; 

Dictionary<string,string> dic = new Dictionary<string,string>(); 

Regex re = new Regex(@"\(([^=]+)=([^=]+)\)"); 

foreach(Match m in re.Matches(sx)) 
{ 
    dic.Add(m.Groups[1].Value, m.Groups[2].Value); 
} 

// extract values, to prove correctness of function 
foreach(var s in dic) 
    Console.WriteLine("{0}={1}", s.Key, s.Value); 
16

RandalSchwartz tiene un rule of thumb: split uso cuando se sabe lo que quiere tirar a la basura o expresiones regulares cuando se sabe lo que quieres conservar

que sepa lo que quiere mantener:

string sx="(colorIndex=3)(font.family=Helvetica)(font.bold=1)"; 

Regex pattern = new Regex(@"\((?<name>.+?)=(?<value>.+?)\)"); 

var d = new Dictionary<string,string>(); 
foreach (Match m in pattern.Matches(sx)) 
    d.Add(m.Groups["name"].Value, m.Groups["value"].Value); 

Con un poco de esfuerzo, puede hacerlo con ToDictionary:

var d = Enumerable.ToDictionary(
    Enumerable.Cast<Match>(pattern.Matches(sx)), 
    m => m.Groups["name"].Value, 
    m => m.Groups["value"].Value); 

No estoy seguro si esto se ve mejor:

var d = Enumerable.Cast<Match>(pattern.Matches(sx)). 
    ToDictionary(m => m.Groups["name"].Value, 
       m => m.Groups["value"].Value); 
+3

+1 ¡Nunca escuché esa regla antes, pero me encanta! :) –

13
string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)"; 

var dict = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries) 
      .Select(x => x.Split('=')) 
      .ToDictionary(x => x[0], y => y[1]); 
+0

Hmmm, acabo de notar que esto es funcionalmente igual a la respuesta de erikkallen, pero usando la sintaxis del método de extensión en lugar de la sintaxis de la consulta. – LukeH

+0

@Luke, para mí tu respuesta es más legible, pero eso podría ser simplemente formatear. –

+0

@Tuzo: generalmente también prefiero la sintaxis del método de extensión, pero creo que todo depende del gusto personal. – LukeH

0

Sólo estoy poniendo esto aquí por referencia ...

Para ASP.net, si desea analizar una cadena desde el lado del cliente en un diccionario Esto es útil ...

Crear una cadena JSON en el lado del cliente, ya sea como esto:

var args = "{'A':'1','B':'2','C':'" + varForC + "'}"; 

o como esto:

var args = JSON.stringify(new { 'A':1, 'B':2, 'C':varForC}); 

ni aun como este:

var obj = {}; 
obj.A = 1; 
obj.B = 2; 
obj.C = varForC; 
var args = JSON.stringify(obj); 

pásalo al servidor ...

continuación, analizar en el lado del servidor de la siguiente manera:

JavaScriptSerializer jss = new JavaScriptSerializer(); 
Dictionary<String, String> dict = jss.Deserialize<Dictionary<String, String>>(args); 

JavaScriptSerializer requiere System.Web.Script.Serialization.

3

Usted puede intentar

string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)"; 

var keyValuePairs = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries) 
      .Select(v => v.Split('=')) 
      .ToDictionary(v => v.First(), v => v.Last()); 
1

A menudo se utiliza para dividir petición HTTP.

Usage: Dictionary<string, string> dict = stringToDictionary("userid=abc&password=xyz&retain=false"); 

public static Dictionary<string, string> stringToDictionary(string line, char stringSplit = '&', char keyValueSplit = '=') 
{ 
    return line.Split(new[] { stringSplit }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Split(new[] { keyValueSplit })).ToDictionary(x => x[0], y => y[1]); ; 
}