需要一些关于Regex匹配/替换模式的帮助

本文关键字:替换 模式 帮助 匹配 Regex | 更新日期: 2023-09-27 18:25:22

我的最终目标是将以下字符串转换为JSON,但我会通过将字段名与每个值组合来实现这一点。

样本数据:

Field1:abc;def;Field2:asd;fgh;

使用Regex.Replace(),我需要它至少看起来像这样:

Field1:abc,Field1:def,Field2:asd,Field2:fgh

最终,如果能在一次通话中通过Regex完成,这个结果将非常棒。

{"Field1":"abc","Field2":"asd"},{"Field1":"def","Field2":"fgh"}

我尝试过这种模式的许多不同变体,但似乎都做不好:

(?:('w+):)*?(?:([^:;]+);)

我能找到的另一个例子是做一些类似的事情,但只是有足够的差异,我无法完全理解

Regex在CDL上重复捕获?

EDIT:

这是我的解决方案。我不会把它作为"解决方案"发布,因为我想把它归功于其他人发布的解决方案。最后,我从每个发布的解决方案中提取了一部分,并提出了这个解决方案。感谢所有发帖的人。我认为这个解决方案编译、执行最快、结果最准确。

    string hbi = "Field1:aaa;bbb;ccc;ddd;Field2:111;222;333;444;";
    Regex re = new Regex(@"('w+):(?:([^:;]+);)+");
    MatchCollection matches = re.Matches(hbi);
    SortedDictionary<string, string> dict = new SortedDictionary<string, string>();
    for (int x = 0; x < matches.Count; x++)
    {
        Match match = matches[x];
        string property = match.Groups[1].Value;
        for (int i = 0; i < match.Groups[2].Captures.Count; i++)
        {
            string key = i.ToString() + x.ToString();
            dict.Add(key, string.Format("'"{0}'":'"{1}'"", property, match.Groups[2].Captures[i].Value));
        }
    }
    Console.WriteLine(string.Join(",", dict.Values));

需要一些关于Regex匹配/替换模式的帮助

现在有两个问题

我不认为正则表达式是处理这个问题的最佳方式。您可能应该从拆分分号开始,然后在结果中循环查找以"Field1:"或"Field2:"开头的值,并将结果收集到Dictionary中。

将其视为伪代码,因为我尚未编译或测试它:

string[] data = input.Split(';');
dictionary<string, string> map = new dictionary<string, string>();
string currentKey = null;
foreach (string value in data)
{
    // This part should change depending on how the fields are defined.
    // If it's a fixed set you could have an array of fields to search,
    // or you might need to use a regular expression.
    if (value.IndexOf("Field1:") == 0 || value.IndexOf("Field2:"))
    {
        string currentKey = value.Substring(0, value.IndexOf(":"));
        value = value.Substring(currentKey.Length+1);
    }
    map[currentKey] = value;
}
// convert map to json

我有一个想法,应该可以用一种更短、更清晰的方式来做这件事。它最终并没有那么短,你可以质疑它是否更清晰。至少这是解决问题的另一种方法。

var str = "Field1:abc;def;Field2:asd;fgh";
var rows = new List<Dictionary<string, string>>();
int index = 0;
string value;
string fieldname = "";
foreach (var s in str.Split(';'))
{
    if (s.Contains(":"))
    {
        index = 0;
        var tmp = s.Split(':');
        fieldname = tmp[0];
        value = tmp[1];
    }
    else
    {
        value = s;
        index++;
    }
    if (rows.Count < (index + 1))
        rows.Insert(index, new Dictionary<string, string>());
    rows[index][fieldname] = value;
}
var arr = rows.Select(dict => 
                   String.Join("," , dict.Select(kv => 
                       String.Format("'"{0}'":'"{1}'"", kv.Key, kv.Value))))
                   .Select(r => "{" + r + "}");
var json = String.Join(",", arr );
Debug.WriteLine(json);

输出:

{"Field1":"abc","Field2":"asd"},{"Field1":"def","Field2":"fgh"}

我会选择RegEx作为解析字符串的最简单、最直接的方法,但很抱歉,朋友,我无法想出一个足够聪明的替换字符串来一次性完成这项工作。

我把它删掉是为了好玩,下面的怪物完成了你需要的,尽管很可怕

        Regex r = new Regex(@"(?<FieldName>'w+:)*(?:(?<Value>(?:[^:;]+);)+)");
        var matches = r.Matches("Field1:abc;def;Field2:asd;fgh;moo;"); // Modified to test "uneven" data as well.
        var tuples = new[] { new { FieldName = "", Value = "", Index = 0 } }.ToList(); tuples.Clear();
        foreach (Match match in matches)
        {
            var matchGroups = match.Groups;
            var fieldName = matchGroups[1].Captures[0].Value;
            int index = 0;
            foreach (Capture cap in matchGroups[2].Captures)
            {
                var tuple = new { FieldName = fieldName, Value = cap.Value, Index = index };
                tuples.Add(tuple);
                index++;
            }
        }
        var maxIndex = tuples.Max(tup => tup.Index);
        var jsonItemList = new List<string>();
        for (int a = 0; a < maxIndex+1; a++)
        {
            var jsonBuilder = new StringBuilder();
            jsonBuilder.Append("{");
            foreach (var tuple in tuples.Where(tup => tup.Index == a))
            {
                jsonBuilder.Append(string.Format("'"{0}'":'"{1}'",", tuple.FieldName, tuple.Value));
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1); // trim last comma.
            jsonBuilder.Append("}");
            jsonItemList.Add(jsonBuilder.ToString());
        }
        foreach (var item in jsonItemList)
        {
            // Write your items to your document stream.
        }