简体   繁体   English

从C#中的格式化字符串解析值

[英]Parsing values from a formatted string in C#

How can I parse multiple values from a formatted string in C#? 如何从C#中的格式化字符串中解析多个值?

The string is in this format: "blah blah blah (foo:this, bar:that)" 字符串的格式为:“blah blah blah(foo:this,bar:that)”

I need to parse out the foo and the bar value. 我需要解析foobar值。 The parentheses are always at the end of the line. 括号总是在行的末尾。

Edit: Sorry... that wasn't very clear. 编辑:对不起......那不是很清楚。 What I meant was I need to know the "foo" value and the "bar" value, so that I can say, somewhere else, "foo is this" and "bar is that". 我的意思是我需要知道“foo”值和“bar”值,以便我可以说,在其他地方,“foo就是这个”,“bar就是那个”。

Thanks 谢谢

EDIT: updated after OP clarification. 编辑:在OP澄清后更新。

This should do: 这应该做:

string input = "blah blah blah (foo:this, bar:that,1:one,2:two)";
string pattern = @"\((?:(?<Values>.*?:[^,\s]+)[,\s]*)+\)";
foreach (Match m in Regex.Matches(input, pattern))
{
    foreach (Capture c in m.Groups["Values"].Captures)
    {
        string[] values = c.Value.Split(':');
        Console.WriteLine("{0} : {1}", values[0], values[1]);
    }
}

This outputs: 这输出:

  • foo : this foo:这个
  • bar : that 吧:那个
  • 1 : one 1:一
  • 2 : two 2:两个

If you need to ensure the match only occurs at the end of the string, rather than match similar formatted values elsewhere in the string, add $ to the end of the pattern: 如果您需要确保匹配仅发生在字符串的末尾,而不是匹配字符串中其他位置的类似格式化值,请将$添加到模式的末尾:

string pattern = @"\((?:(?<Values>.*?:[^,\s]+)[,\s]*)+\)$";

Regular expressions should not be used for parsing if possible, only lexing. 正则表达式不应该用于解析,如果可能的话,只有lexing。 Pass the lexed tokens into a finite state machine for the actual parsing. 将lexed标记传递给有限状态机进行实际解析。

I'm making quite a few assumptions here based on your question, but this should get you headed in the right direction. 我在这里基于你的问题做了很多假设,但这应该让你朝着正确的方向前进。

#!/usr/bin/perl

my $input = "blah blah blah (foo:this, bar:that, foo2:150)";

my @ray = ($input =~ /.*?:(\w*)/g);
foreach $x (@ray)
{
    print "Value: '$x'\n";
}

Output: 输出:

Value: 'this'
Value: 'that'
Value: '150'

As for .NET you can use captures like this: 至于.NET,你可以使用这样的捕获:

> $s = "blah blah blah (foo:this, bar:that)"
> $result = [regex]::Match($s, '[^(]*\((?:\w+:(?<t>\w+),\s*)*\w+:(?<t>\w+)\)$')
> $result.Groups

Groups   : {blah blah blah (foo:this, bar:that), that}
Success  : True
Captures : {blah blah blah (foo:this, bar:that)}
Index    : 0
Length   : 35
Value    : blah blah blah (foo:this, bar:that)

Success  : True
Captures : {this, that}
Index    : 30
Length   : 4
Value    : that

> $result.Groups[1].captures
Index                                          Length Value
-----                                          ------ -----
20                                               4 this
30                                               4 that

it is code in PowerShell. 它是PowerShell中的代码。 However, PowreShell is based on .NET, so this should work in .NET. 但是,PowreShell基于.NET,所以这应该适用于.NET。

The parsing expression is based on the example you posted, so it skips everything up to ( and then begins parsing the values. Note that (?:..) is noncapturing group so it doesn't appear in results. 解析表达式基于您发布的示例,因此它会跳过所有内容(然后开始解析值。请注意(?:..)是非捕获组,因此它不会出现在结果中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM