我想匹配以下模式:
key="value" key="value" key="value" key="value" ...
其中键和值为[a-z0-9] +,两者都应分组(2组,“ - 字符可以匹配或跳过”)
不应匹配的输入:
key =“value”key =“value”(对之间没有空格)
现在我得到了这个(不是.NET语法):
([a-z0-9]+)=(\"[a-z0-9]+\")(?=\s|$)
问题在于,它与输入中的key4 =“value4”匹配:
key3="value3"key4="value4"
答案 0 :(得分:2)
规格不是很清楚,但您可以尝试:
(?<!\S)([a-z0-9]+)=("[a-z0-9]+")(?!\S)
或者,作为C#字符串文字:
"(?<!\\S)([a-z0-9]+)=(\"[a-z0-9]+\")(?!\\S)"
这使用负面外观来确保键值对既不在前面也不在后面跟着非空白字符。
以下是一个示例代码段(as seen on ideone.com):
var input = "key1=\"value1\" key2=\"value2\"key3=\"value3\" key4=\"value4\"";
Console.WriteLine(input);
// key1="value1" key2="value2"key3="value3" key4="value4"
Regex r = new Regex("(?<!\\S)([a-z0-9]+)=(\"[a-z0-9]+\")(?!\\S)");
foreach (Match m in r.Matches(input)) {
Console.WriteLine(m);
}
// key1="value1"
// key4="value4"
您可以使用Regex.IsMatch
查看输入字符串是否与正确的输入模式匹配。您还可以使用相同的模式来提取键/值,这要归功于.NET正则表达式允许您访问单个捕获。
string[] inputs = {
"k1=\"v1\" k2=\"v2\" k3=\"v3\" k4=\"v4\"",
"k1=\"v1\" k2=\"v2\"k3=\"v3\" k4=\"v4\"",
" k1=\"v1\" k2=\"v2\" k3=\"v3\" k4=\"v4\" ",
" ",
" what is this? "
};
Regex r = new Regex("^\\s*(?:([a-z0-9]+)=\"([a-z0-9]+)\"(?:\\s+|$))+$");
foreach (string input in inputs) {
Console.Write(input);
if (r.IsMatch(input)) {
Console.WriteLine(": MATCH!");
Match m = r.Match(input);
CaptureCollection keys = m.Groups[1].Captures;
CaptureCollection values = m.Groups[2].Captures;
int N = keys.Count;
for (int i = 0; i < N; i++) {
Console.WriteLine(i + "[" + keys[i] + "]=>[" + values[i] + "]");
}
} else {
Console.WriteLine(": NO MATCH!");
}
}
以上打印(as seen on ideone.com):
k1="v1" k2="v2" k3="v3" k4="v4": MATCH!
0[k1]=>[v1]
1[k2]=>[v2]
2[k3]=>[v3]
3[k4]=>[v4]
k1="v1" k2="v2"k3="v3" k4="v4": NO MATCH!
k1="v1" k2="v2" k3="v3" k4="v4" : MATCH!
0[k1]=>[v1]
1[k2]=>[v2]
2[k3]=>[v3]
3[k4]=>[v4]
: NO MATCH!
what is this? : NO MATCH!
验证整个输入的模式基本上是:
maybe leading
spaces ___ end of string anchor
| /
^\s*(entry)+$
| \
beginning \__ one or more entry
of string
anchor
每个条目都是:
key=value(\s+|$)
即,键/值对后跟空格或字符串的结尾。
答案 1 :(得分:2)
我认为SilentGhost提议是关于使用String.Split()
像这样:
String keyValues = "...";
foreach(String keyValuePair in keyValues.Split(' '))
Console.WriteLine(keyValuePair);
这绝对更快更简单。
答案 2 :(得分:1)
像你使用前瞻一样使用lookbehind:
(?<=\s|^)([a-z0-9]+)=(\"[a-z0-9]+\")(?=\s|$)
答案 3 :(得分:1)
我是第二个Jens' answer(但我仍然对其他人的答案不予评论)。
另外,我发现this Regular Expressions Reference网站非常棒。在Advanced页面上有关于Lookaround的一半部分,以及关于Lookbehind的一些进一步说明。