你能改进这个C#正则表达式代码吗?
在一个程序中,我正在读取一些数据文件,其中一部分被格式化为一系列记录,每个记录都放在方括号内。每个记录包含一个节标题和一系列键/值对 我最初编写代码来循环并提取这些值,但决定可以使用正则表达式更优雅地完成。下面是我的结果代码(我刚刚在一个控制台应用程序中破解了它-所以要知道变量名不是很好,等等) 你能提出改进建议吗?我觉得不需要做两个匹配和一个子串,但我不知道如何在一大步中完成这一切:你能改进这个C#正则表达式代码吗?,c#,regex,C#,Regex,在一个程序中,我正在读取一些数据文件,其中一部分被格式化为一系列记录,每个记录都放在方括号内。每个记录包含一个节标题和一系列键/值对 我最初编写代码来循环并提取这些值,但决定可以使用正则表达式更优雅地完成。下面是我的结果代码(我刚刚在一个控制台应用程序中破解了它-所以要知道变量名不是很好,等等) 你能提出改进建议吗?我觉得不需要做两个匹配和一个子串,但我不知道如何在一大步中完成这一切: string input = "[section1 key1=value1 key2=value2][sect
string input = "[section1 key1=value1 key2=value2][section2 key1=value1 key2=value2 key3=value3][section3 key1=value1]";
MatchCollection matches=Regex.Matches(input, @"\[[^\]]*\]");
foreach (Match match in matches)
{
string subinput = match.Value;
int firstSpace = subinput.IndexOf(' ');
string section = subinput.Substring(1, firstSpace-1);
Console.WriteLine(section);
MatchCollection newMatches = Regex.Matches(subinput.Substring(firstSpace + 1), @"\s*(\w+)\s*=\s*(\w+)\s*");
foreach (Match newMatch in newMatches)
{
Console.WriteLine("{0}={1}", newMatch.Groups[1].Value, newMatch.Groups[2].Value);
}
}
您应该能够对嵌套组执行以下操作:
pattern = @"\[(\S+)(\s+([^\s=]+)=([^\s\]]+))*\]"
我没有在C#中对其进行测试,也没有在匹配中循环,但结果看起来很正确您应该利用集合来获取每个密钥。因此,类似于以下内容:
string input = "[section1 key1=value1 key2=value2][section2 key1=value1 key2=value2 key3=value3][section3 key1=value1]";
Regex r = new Regex(@"(\[(\S+) (\s*\w+\s*=\s*\w+\s*)*\])", RegexOptions.Compiled);
foreach (Match m in r.Matches(input))
{
Console.WriteLine(m.Groups[2].Value);
foreach (Capture c in m.Groups[3].Captures)
{
Console.WriteLine(c.Value);
}
}
结果输出:
section1
key1=value1
key2=value2
section2
key1=value1
key2=value2
key3=value3
section3
key1=value1
这将匹配所有键/值对
var input = "[section1 key1=value1 key2=value2][section2 key1=value1 key2=value2 key3=value3][section3 key1=value1]";
var ms = Regex.Matches(input, @"section(\d+)\s*(\w+=\w+)\s*(\w+=\w+)*");
foreach (Match m in ms)
{
Console.WriteLine("Section " + m.Groups[1].Value);
for (var i = 2; i < m.Groups.Count; i++)
{
if( !m.Groups[i].Success ) continue;
var kvp = m.Groups[i].Value.Split( '=' );
Console.WriteLine( "{0}={1}", kvp[0], kvp[1] );
}
}
var input=“[section1key1=value1key2=value2][section2key1=value1key2=value2key3=value3][section3key1=value1]”;
var ms=Regex.Matches(输入,@“节(\d+)\s*(\w+=\w+)\s*(\w+=\w+)*”);
foreach(匹配m,毫秒)
{
Console.WriteLine(“节”+m.Groups[1]。值);
对于(变量i=2;i
我更喜欢命名捕获、格式和清晰度:
string input = "[section1 key1=value1 key2=value2][section2 key1=value1 key2=value2 key3=value3][section3 key1=value1]";
MatchCollection matches = Regex.Matches(input, @"\[
(?<sectionName>\S+)
(\s+
(?<key>[^=]+)
=
(?<value>[^ \] ]+)
)+
]", RegexOptions.IgnorePatternWhitespace);
foreach(Match currentMatch in matches)
{
Console.WriteLine("Section: {0}", currentMatch.Groups["sectionName"].Value);
CaptureCollection keys = currentMatch.Groups["key"].Captures;
CaptureCollection values = currentMatch.Groups["value"].Captures;
for(int i = 0; i < keys.Count; i++)
{
Console.WriteLine("{0}={1}", keys[i].Value, values[i].Value);
}
}
string input=“[section1key1=value1key2=value2][section2key1=value1key2=value2key3=value3][section3key1=value1]”;
MatchCollection matches=Regex.matches(输入@)\[
(?\S+)
(\s+
(?[^=]+)
=
(?[^ \] ]+)
)+
]“,RegexOptions.IgnorePatternWhitespace);
foreach(在匹配项中匹配currentMatch)
{
WriteLine(“Section:{0}”,currentMatch.Groups[“sectionName”].Value);
CaptureCollection keys=currentMatch.Groups[“key”]。捕获;
CaptureCollection values=currentMatch.Groups[“value”]。捕获;
对于(int i=0;i
Nice,我不知道如何使用IgnorePatternWhitespace选项来设置这样的正则表达式格式。谢谢你的提示。+1再次用于RegexOptions。IgnorePatternWhitespace是的,用于可读性+1我也喜欢命名捕获。它们使代码可读且易于理解。我在实践中也喜欢命名捕获,但有时使用j回答问题时,为了简洁起见,请使用ust数字。:)