2011-02-09 13 views
1

我如何爱正则表达式!正则表达式问题,提取数据给组

我有这将是XML的一个错位的形式,像一个字符串:

<Category>DIR</Category><Location>DL123A</Location><Reason>Because</Reason><Qty>42</Qty><Description>Some Desc</Description><IPAddress>127.0.0.1</IPAddress> 

一切都将在同一行,但在“头”往往会有所不同。

所以我需要做的是提取从上面的字符串中的所有信息,把它变成一个字典/哈希表

-

string myString = @"<Category>DIR</Category><Location>DL123A</Location><Reason>Because</Reason><Qty>42</Qty><Description>Some Desc</Description><IPAddress>127.0.0.1</IPAddress>"; 

//this will extract the name of the label in the header 
Regex r = new Regex(@"(?<header><[A-Za-z]+>?)"); 

//Create a collection of matches 
MatchCollection mc = r.Matches(myString); 

foreach (Match m in mc) 
{ 
    headers.Add(m.Groups["header"].Value); 
} 


//this will try and get the values. 
r = new Regex(@"(?'val'>[A-Za-z0-9\s]*</?)"); 

mc = r.Matches(myString); 

foreach (Match m in mc) 
{ 
    string match = m.Groups["val"].Value; 
    if (string.IsNullOrEmpty(match) || match == "><" || match == "> <") 
     continue; 
    else 
     values.Add(match); 
} 

- 我砍死一起从以前的工作正确的正则表达式我可以。 但它并不按照我想要的方式工作。

的“标头”也拉动角括号中。

在“值”在很多空箱拉动(因此狡猾的if语句在循环中)。它也不适用于句点,逗号,空格等字符串。

如果我可以结合这两个语句,所以我不必循环遍历正则表达式两次也会好得多。

任何人都可以给我一些信息,我可以改善它吗?

回答

3

如果它看起来像XML,为什么不使用.NET的XML解析器的功能?所有你需要做的就是添加一个根元素周围:

string myString = @"<Category>DIR</Category><Location>DL123A</Location><Reason>Because</Reason><Qty>42</Qty><Description>Some Desc</Description><IPAddress>127.0.0.1</IPAddress>"; 

var values = new Dictionary<string, string>(); 
var xml = XDocument.Parse("<root>" + myString + "</root>"); 
foreach(var e in xml.Root.Elements()) { 
    values.Add(e.Name.ToString(), e.Value); 
} 
+0

打我吧。当你可以的时候,你应该总是倾向于使用正则表达式的XML解析器。这就是他们的目的。 – 2011-02-09 14:26:11

1

这应该剥去尖括号:

Regex r = new Regex(@"<(?<header>[A-Za-z]+)>"); 

,这应该摆脱空的空间:

r = new Regex(@">\s*(?'val'[A-Za-z0-9\s]*)\s*</"); 
1

这将匹配头,不<>:

(?<=<)(?<header>[A-Za-z]+)(?=>) 

这将让所有的值(我不知道什么可以接受的值):

(?<=>)(?'val'[^<]*)(?=</) 

然而,这是所有的XML,因此您可以:

XDocument doc = XDocument.Parse(string.Format("<root>{0}</root>",myString)); 
var pairs = doc.Root.Descendants().Select(node => new KeyValuePair<string, string>(node.Name.LocalName, node.Value));