【问题标题】:Regex for string split twice字符串拆分两次的正则表达式
【发布时间】:2015-05-27 05:49:04
【问题描述】:

我有一个在数组中被分割两次的字符串。这是一个例子:

Obj1:Val1|Obj2:Val2|Obj3:Val3

请帮我用正则表达式来获取第一个字符串的数组:

Obj1
Obj2
Obj3

然后获取另一个正则表达式

Val1
Val2
Val3

我不想重复。我想一次性得到正则表达式的结果。

【问题讨论】:

  • 您使用的是什么语言?到目前为止你尝试了什么?
  • 我正在使用 c#,但这有关系吗?
  • 是的,它非常重要。
  • 这很重要,因为正则表达式引擎不一样,解析算法和模式定义语言存在差异。

标签: c# .net regex


【解决方案1】:

由于您使用的是 C#,因此您可以先使用 | 拆分字符串,然后您将拥有带有 : 作为分隔符的字符串列表,因此您可以使用 : 拆分子列表并使用 zip function 来获取对象和值的列表。

但作为一种直接的方式,您可以使用以下正则表达式:

for values(第一组):

:(.*?)(\||$)

for objects(第二组):

(\||^)(.*?):

【讨论】:

  • 这给出 : 和 |结果中的字符也是如此。如何修剪那些?
【解决方案2】:

您可以使用以下方式进行拆分:

[:|]

偶数索引将给出Obj1 Obj2 Obj3 并从数组的奇数索引中获取Val1 Val2 Val3

或者..

您可以使用[|] 拆分正则表达式,然后使用[:] 拆分每个值。将[0] 存储在一个数组中,将[1] 存储在另一个数组中..

编辑:

对于Obj 的列表,您可以使用以下正则表达式进行拆分:

:\w+(?:\||$)

对于Val 的列表,您可以使用以下正则表达式进行拆分:

(?:^|\|)\w+:

【讨论】:

  • 这不会获取所有 Obj* 的列表
  • 我不想重复。我想要一次从 Regex 得到的结果
  • 这给出 : 和 |结果中的字符也是如此。如何修剪那些?
【解决方案3】:

使用命名匹配捕获来提取信息。下面的正则表达式获取键值(第一个)和值值(第二个)并最终创建键值对对象。

string data ="Obj1:Val1|Obj2:Val2|Obj3:Val3";
string pattern = @"(?<Key>[^:]+):(?<Value>[^|]+)+\|?";

  Regex.Matches(data, pattern)
       .OfType<Match>()
       .Select (mt => new KeyValuePair<string,string>(mt.Groups["Key"].Value,  
                                                      mt.Groups["Value"].Value) );

注意KeyValuePair 投影是可选的,您可以简单地通过mt.Groups["Key"].Value 自行提取信息。

这是上述正则表达式/linq 投影的结果:

【讨论】:

    【解决方案4】:

    您不需要正则表达式。使用拆分和 LINQ:

    var str = "Obj1:Val1|Obj2:Val2|Obj3:Val3";
    var arr = str.Split(new[] {'|',':'});
    // And then either these 2 lines to get Objs and Vals into different arrays
    var vals  = arr.Where((c,i) => i % 2 != 0).ToArray();
    var objs = arr.Where((c,i) => i % 2 == 0).ToArray();
    // Or into a key-value pair array
    var key_value_array = 
         arr.Where((c, i) => i % 2 == 0)
            .Zip(arr.Where((c, i) => i % 2 != 0), 
                 (key, value) => new KeyValuePair<string, string>(key, value))
            .ToArray();
    

    输出:

    【讨论】:

    • arr 上调用ToList() 是不必要的,因为底层对象不是可查询的; for split 返回一个可枚举的 string[] 结果。
    • 是的,你是对的。无需将string[] 转换为List&lt;string&gt;,已更新。我只是不确定,也没有办法检查。
    • 使用 Linqpad。还要将此添加到您对Zip 的答案中,将结果添加到 KeyValue 对中:arr.Where((c,i) =&gt; i % 2 != 0) .Zip(arr.ToList().Where((c,i) =&gt; i % 2 == 0) , (key, value) =&gt; new KeyValuePair&lt;string,string&gt;(key,value))
    • 哎呀,我的逻辑在哪里反转了,对于键和值。
    • @OmegaMan:谢谢你的提示。现在,OP 似乎有很多选择 :)
    【解决方案5】:

    要获得Obj 匹配项,您可以通过以下方式拆分

    :[^|]+(?:\||$)
    

    要获得Val 字符串拆分

    (^|\|)[^:]+:
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 2011-06-18
      • 2011-10-16
      相关资源
      最近更新 更多