C# 需要有关正则表达式匹配/替换模式的帮助吗
我在这里的最终目标是将以下字符串转换为JSON,但我会满足于通过将字段名与每个值相结合来更进一步的要求 样本数据:C# 需要有关正则表达式匹配/替换模式的帮助吗,c#,regex,C#,Regex,我在这里的最终目标是将以下字符串转换为JSON,但我会满足于通过将字段名与每个值相结合来更进一步的要求 样本数据: Field1:abc;def;Field2:asd;fgh; 使用Regex.Replace(),我需要它至少如下所示: Field1:abc,Field1:def,Field2:asd,Field2:fgh 最终,如果可以通过Regex在一次调用中完成,那么这个结果将非常棒 {"Field1":"abc","Field2":"asd"},{"Field1":"def","Fi
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+):)*?(?:([^:;]+);)
我能找到的另一个例子是做了一些类似的事情,但只是有足够的差异,我不能完全指出
这是我的解决办法。我不打算把它作为一个“解决方案”发布,因为我想把别人发布的解决方案归功于我。最后,我从每个贴出的解决方案中拿出一块,并提出了这个解决方案。感谢所有发帖的人。我认为这个解决方案编译、执行速度最快,结果最准确
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));
string hbi=“Field1:aaa;bbb;ccc;ddd;Field2:111;222;333;444;”;
正则表达式re=新正则表达式(@“(\w+):(?:([^:;]+);)+”;
MatchCollection匹配=重新匹配(hbi);
SortedDictionary dict=新SortedDictionary();
for(int x=0;x
我认为正则表达式不是处理这个问题的最佳方法。您可能应该首先以分号分隔,然后在结果中循环查找以“Field1:”或“Field2:”开头的值,并将结果收集到字典中
将其视为伪代码,因为我没有编译或测试它:
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
string[]data=input.Split(“;”);
字典映射=新字典();
字符串currentKey=null;
foreach(数据中的字符串值)
{
//此部分应根据字段的定义方式进行更改。
//如果它是一个固定的集合,您可以搜索一组字段,
//或者您可能需要使用正则表达式。
if(value.IndexOf(“Field1:”)==0 | | value.IndexOf(“Field2:”)
{
字符串currentKey=value.Substring(0,value.IndexOf(“:”);
value=value.Substring(currentKey.Length+1);
}
map[currentKey]=值;
}
//将映射转换为json
我会选择正则表达式作为解析字符串的最简单、最直接的方法,但很抱歉,伙计,我不能想出一个足够聪明的替换字符串来一次性完成这项工作
我把它砍掉是为了好玩,下面的怪物完成了你需要的东西,尽管很可怕-/
Regex r=newregex(@“(?\w+:)*(?:(?(?:[^:;]+);)+))”;
var matches=r.matches(“字段1:abc;def;字段2:asd;fgh;moo;”;//修改以测试“不均匀”数据。
var tuples=new[]{new{FieldName=“”,Value=“”,Index=0}}}.ToList();tuples.Clear();
foreach(匹配中的匹配)
{
var matchGroups=match.Groups;
var fieldName=matchGroups[1]。捕获[0]。值;
int指数=0;
foreach(匹配组[2]中的捕获上限。捕获)
{
var tuple=new{FieldName=FieldName,Value=cap.Value,Index=Index};
tuples.Add(tuple);
索引++;
}
}
var maxIndex=tuples.Max(tup=>tup.Index);
var jsonitmlist=新列表();
对于(int a=0;atup.Index==a))
{
追加(string.Format(“\”{0}\”:\“{1}\”,”,tuple.FieldName,tuple.Value));
}
jsonBuilder.Remove(jsonBuilder.Length-1,1);//修剪最后一个逗号。
jsonBuilder.Append(“}”);
添加(jsonBuilder.ToString());
}
foreach(jsonItemList中的变量项)
{
//将项目写入文档流。
}
我有一个想法,应该可以用一种更简短、更清晰的方式来完成。最后它没有那么短,你可以质疑它是否更清晰。至少这是另一种解决问题的方法
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);
如果LINQ的性能接近Regex,我很高兴。在大输入字符串上进行比较会很有趣,我同意。与我试图转换的数据相比,这里显示的相同数据非常小。真正的对象包含31个字段,可能包含100-200个对象。@Chris_Gessler,有没有一种可预测的方法来识别字段名?我猜这不是真正意义上的场1,场2。分隔符“;”用于分隔元组中的值以及元组中的值,这使得它很棘手。或者它总是被修饰为字段名,两个值,然后是字段分隔符?字段后面总是跟一个冒号。值后面总是跟一个分号是。。。“奥勒蛮力”的方式。循环。使用C#4.0、Linq、动力学、泛型等。。。必须有一种方法可以将这种可预测的格式反序列化为JSON而不使用循环。我确信有一种方法可以避免循环,但为什么要让它更复杂呢?即使你看不到循环,Linq等的循环仍然存在。我的观点是C#自1.0以来已经走过了很长的路。我相信有一个正则表达式模式可以工作,所以我宁愿使用该解决方案,将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"}