好吧,我提前警告你,我对正则表达的理解非常有限(多年来我一直尽力学习它们,但说实话,我认为它们只会吓到我。)
假设我有以下字符串:
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 :(得分:3)
|
在正则表达式中具有特殊含义(patA|patB
匹配patA
或patB
)。逃脱|
。
使用非贪婪的匹配(.*?
):
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);
BTW,在表达正则表达式时使用逐字字符串文字(@"verbatim string literal"
)。
答案 1 :(得分:2)
如果您只关心按键,为什么不尝试使用匹配而不是使用分割:
@"[^=|]+(?==)"
如果密钥不能包含等号=
或竖线|
,则上述表达式将匹配一个或多个不是=
或{{1}的字符其后跟一个等号|
,从而匹配键。
在C#中:
=
答案 2 :(得分:1)
另一种方法是在没有正则表达式的情况下执行此操作,因为字符串操作非常基本:
string[] keys =
keyValues.Split(new string[]{"||"}, StringSplitOptions.None)
.Select(s => s.Substring(0, s.IndexOf('='))).ToArray();
将正则表达式保留为高级字符串操作。 :)
(与使用正则表达式相比,测试此解决方案的性能时,显示速度提高了约40倍。)
答案 3 :(得分:0)
分割在@"=[^|]*(?:\|\||$)"
上
如果您需要更多保证,请使用@"=[^=|]*(?:\|\||$)"
编辑消耗没有分隔符的结束。
如果它在C#中,尝试使用无空元素。