我有以下输入内容:
-key1:"val1" -key2: "val2" -key3:(val3) -key4: "(val4)" -key5: val5 -key6: "val-6" -key-7: val7 -key-eight: "val 8"
仅对模式进行以下假设:
-
开头,后跟以:
分隔的值如何匹配并提取每个键及其对应的值?
到目前为止,我已经提出了以下 regex
: -(?<key>\S*):\s?(?<val>\S*)
但是它当前不匹配最后一个参数的完整值,因为它包含一个空格,但是我不知道如何匹配它。
预期输出应为:
非常感谢您的帮助。
答案 0 :(得分:4)
假设您只想允许不在开头或结尾的空格字符,请将正则表达式更改为:
-(?<key>\S*):\s?(?<val>\S+(\s*[^-\s])*)
这假定空格前面的字符-
毫无疑问地表示一个新键正在开始,它不能是任何值的一部分。
对于此示例:
-key: value -key2: value with whitespace -key3: value-with-hyphens -key4: v
匹配项是:
-key: value
,-key2: value with whitespace
,-key3: value-with-hyphens
,-key4: v
。
它在您提供的示例中也能很好地工作。
答案 1 :(得分:1)
我想您要保留方括号和引号,因为这是您在给出的示例中所做的事情?如果是这样,则应该可以进行以下操作:
-(?<key>\S+):+\s?(?<val>\S+\s?\d+\)?\"?)
这确实假定所有val都以数字结尾。
编辑: 鉴于val并不总是以数字结尾,但是我想它总是以val开头,这就是我的意思:
-(?<key>\S+):+\s?(?<val>\"?\(?(val)+\s?\S+)
似乎正常工作...
答案 2 :(得分:1)
技术含量低(非正则表达式)的解决方案,仅供选择。修剪饰条,ToDictionary
(如果需要)
var results = input.Split(new[] { " -" }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim('-').Split(':'));
输出
key1 -> "val1"
key2 -> "val2"
key3 -> (val3)
key4 -> "(val4)"
key5 -> val5
key6 -> "val-6"
key-7 -> val7
key8 -> "val 8"
答案 3 :(得分:1)
答案 4 :(得分:0)
这应该可以解决问题
-(?<key>\S*):\s*(?<value>(?(?=")((")(?:(?=(\\?))\2.)*?\1))(\S*))
可以找到一个示例链接here。
基本上可以,如果/是否/然后检测该值是否包含"
作为(?(?=")(true regex)(false regex)
,则错误的正则表达式是您的\S*
,而真正的正则表达式将尝试匹配开始/结束引号{ {1}}。