且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当键本身是分隔符时,如何从字符串中提取键值对?

更新时间:2023-02-26 09:16:01

忽略已知的一组键,并假设每个键仅出现一次:

Ignoring the known set of keys, and assuming each key appears only once:

string str = "V1,B=V1,C=V1,V2,V3,D=V1,V2,A=V1,=V2,V3";

var splitByEqual = new[] {'='};

var values = Regex.Split(str, @",(?=\w+=)")
    .Select(token => token.Split(splitByEqual, 2))
    .ToDictionary(pair => pair.Length == 1 ? "" : pair.First(),
                  pair => pair.Last());

  • 正则表达式为非常简单:用逗号分隔,后跟一个密钥(任何字母数字)和等号. (如果我们允许A=V1,V2=V3,则将无效)
  • 现在我们有了集合{V1B=V1C=V1,V2,V3D=V1,V2A=V1,=V2,V3}.我们将其除以=,但不超过一次.
  • 接下来,我们创建一个字典.这条线有点难看,但并不是太重要-我们已经有了所需的数据.我还使用了空字符串而不是null.
    • The regex is pretty simple: split by commas that are followed by a key (any alphanumeric) and an equal sign. (If we allow A=V1,V2=V3 this wouldn't work)
    • Now we have the collection {V1,B=V1,C=V1,V2,V3,D=V1,V2,A=V1,=V2,V3}. We split that by =, but not more than once.
    • Next we create a dictionary. This line is a little ugly, but isn't too important - we already have the data we need. I'm also using an empty string instead of null.
    • 如果我们确实想使用已知的键列表,可以将模式更改为:

      If we do want to use the known list of keys, we can change the pattern to:

var splitPattern = @",(?=(?:" + String.Join("|", keys.Select(Regex.Escape))) + ")=)";

并使用Regex.Split(str, splitPattern).