2013-10-29 21 views
0

好吧,我提前警告你,我对正则表达式的理解是非常有限的(多年来,我尽我所能学习它们,但说实话,我认为他们只是吓唬我)使用正则表达式创建字符串数组

比方说,我有以下字符串:

string keyValues = "CustomerId=1||OrderId=12||UserId=a1dcd568-f129-419b-b51e-be2dbb67de0f" 

此字符串表示键值对,由用户定义的字符串(在这种情况下||分隔)(例如,key1=value1||key2=value2)。我试图从这个字符串中提取密钥并将它们存储在一个数组中。该数组是这样的:

{"CustomerId", "OrderId", "UserId"} 

我能想到的最好的办法是使用正则表达式(如果有人有更好的解决办法,请分享)。这里就是我想要做的事:

string delimiter = "||"; 
string[] keys = Regex.Split(keyValues, "=.*" + delimiter); 

我可能是错的,但我的理解是,这个正则表达式应该找到与=开始,以delimiter结尾的字符串,与任何数量的方式之间的任何字符。这将在那些位置分割字符串,留下我与原来的钥匙,而是,我的钥匙阵列看起来像这样:

{"", "C", "u", "s", "t", "o", "m", "e", "r", "I", "d", "", "", ...} 

正如你所看到的,=value||部分被剥离。谁能告诉我我做错了什么?

编辑

在我的情况下,分隔符||是一个变量。我没有提到这一点,因为我认为我可以用delimiter替换对||的任何引用。从大多数给出的答案中,我现在看到这是一个重要的细节。

+0

这两个网站可能真的有助于理解正则表达式: HTTP:/ /www.google.com/support/enterprise/static/postini/docs/admin/en/admin_ee_cu/cm_regex.html和 http://gskinner.com/RegExr/ – Billy

+0

@Billy:即[Postini的](HTTP: //www.google.com/support/enterprise/static/postini/docs/admin/en/admin_ee_cu/cm_regex.html)页面只覆盖了POSIX ERE的味道,这是极其有限的,并与.NET的正则表达式不兼容。 [RegExr](http://gskinner.com/RegExr/)使用A​​ctionScript风格,它更加兼容,但功能仍然非常缺乏。 ** [本网站](http://www.regular-expressions.info/)**更有用,并且MS自己的** [docs](http://msdn.microsoft.com/en-us/ library/hs600312(v = vs.110).aspx)**非常好。 –

+0

@Alan Moore:你说的没错。我还从您分享的网站上获取了大量信息,但这是一整套信息。我认为一些基本的解释会很好:)。 – Billy

回答

3

|在正则表达式中具有特殊含义(patA|patBpatApatB匹配)。逃脱|

使用非贪婪匹配(.*?):

string delimiter = "||"; 
string[] keys = Regex.Split(keyValues, @"=.*?" + Regex.Escape(delimiter)); 

这会给你{"CustomerId", "OrderId", "UserId=a1dcd568-f129-419b-b51e-be2dbb67de0f"}

Matches与前向断言是比较合适的:

string delimiter = "||"; 
string keyValues = "CustomerId=1||OrderId=12||UserId=a1dcd568-f129-419b-b51e-be2dbb67de0f"; 
string pattern = @"(?<=^|" + Regex.Escape(delimiter) + @")\w+(?==)"; 
var keys = Regex.Matches(keyValues, pattern); 

顺便说一句,使用逐字字符串(@"verbatim string literal")当快速正则表达式。

Demo

2

如果你只是关心的钥匙,为什么不试着用一根火柴,而不是分裂的使用:

@"[^=|]+(?==)" 

如果密钥不能包含等号=或竖线|,则上面的表达式将匹配一个或多个字符不=|,其后面跟着一个等号=,从而匹配密钥。

在C#:

var input = "CustomerId=1||OrderId=12||UserId=a1dcd568-f129-419b-b51e-be2dbb67de0f"; 
var results = Regex.Matches(input, @"[^=|]+(?==)"); 
0

分割上@"=[^|]*(?:\|\||$)"
如果你需要更多的保证,使用@"=[^=|]*(?:\|\||$)"

编辑在没有分隔符存在消费端。
尽量只使用如果在C#中没有空白元。

1

另一种方法是做到这一点没有一个正则表达式,为字符串操作是非常基本的:

string[] keys = 
    keyValues.Split(new string[]{"||"}, StringSplitOptions.None) 
    .Select(s => s.Substring(0, s.IndexOf('='))).ToArray(); 

保持正则表达式,以先进的字符串操作。 :)

(当测试这个解决方案相比,使用正则表达式的性能,这表明要快约40倍)。

相关问题