如何从C#中的正则表达式的字符串中获取一个部分

时间:2016-10-21 06:51:39

标签: c# regex

如何获得'姓名'值和'年龄'值?

案例1数据:

aaa bbbb; Name=John Lewis; ccc ddd; Age=20;

案例2数据:

AAA bbbb; Age=21;

我的正则表达式:

(?:Name=(?'name'[\w\b]+)\;)[\s\S]*Age=(?'age'\d+)\;?

但无法获得价值(姓名,年龄)。

4 个答案:

答案 0 :(得分:1)

这是你想要的正则表达式。 (?<Key>\w+?)=(?<Value>(?:\w|\s)+);

此模式将键/值对捕获到命名组

如果密钥名称包含空格,则此解决方案将无法正常运行。

C#用法

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

public class Test
{
    public static void Main()
    {
        string input = @"aaa bbbb; Name=John Lewis; ccc ddd; Age=20;";
        string pattern = @"(?<Key>\w+?)=(?<Value>(?:\w|\s)+);";

        var matches = Regex.Matches(input, pattern);
        foreach (var match in matches.OfType<Match>())
        {
            string key = match.Groups["Key"].Value;
            string value = match.Groups["Value"].Value;
            Console.WriteLine(key + ": " + value);
        }
    }
}

<强>输出

Name: John Lewis
Age: 20

答案 1 :(得分:1)

案例1:只有Name是可选的

针对您的案例的正则表达式应考虑可选的Name字段。

(?:\bName=(?<Name>[^;]+).*?;\s+)?\bAge=(?<Age>\d+)
^^^                            ^^

请参阅regex demo

如果NameAge数据位于不同的行,请使用带有RegexOptions.Singleline标记的正则表达式。

<强>详情:

  • (?:\bName=(?<Name>[^;]+).*?;\s+)? - 一个可选的子模式字符串
    • \bName= - 整个单词“姓名”+ =
    • (?<Name>[^;]+) - 群组“名称”捕获除;
    • 以外的1个字符
    • .*? - 任何0 +字符(如果未使用(?s),则为换行符除外)
    • ; - 分号
    • \s+ - 一个或多个空格
  • \bAge= - 整个字Age + =
  • (?<Age>\d+) - 捕获“年龄”组匹配1位数字。

C# demo

var strs = new[] { "aaa bbbb; Name=John Lewis; ccc ddd; Age=20;", "AAA bbbb; Age=21;" };
var pattern = @"(?:\bName=(?<Name>[^;]+).*?;\s+)?\bAge=(?<Age>\d+)";
foreach (var str in strs) 
{
    var result = Regex.Match(str, pattern);
    if (result.Success) 
        Console.WriteLine("Name: \"{0}\", Age: \"{1}\"", result.Groups["Name"].Value, result.Groups["Age"].Value);
}
// => Name: "John Lewis", Age: "20"
//    Name: "", Age: "21"

案例2:NameAge都是可选的

为这两个字段使用可选组:

(?:\bName=(?<Name>[^;]+).*?;\s+)?(?:\bAge=(?<Age>\d+))?
^^^                            ^^^^^                 ^^

请参阅this C# demo

var strs = new[] { "aaa bbbb; Name=John Lewis; ccc ddd; Age=20;", "AAA bbbb; Age=21;", "Irrelevant", "My Name=Wiktor; no more data" };
var pattern = @"(?:\bName=(?<Name>[^;]+).*?;\s+)?(?:\bAge=(?<Age>\d+))?";
foreach (var str in strs) 
{
    var results = Regex.Matches(str, pattern)
        .Cast<Match>()
        .Where(m => m.Groups["Name"].Success || m.Groups["Age"].Success)
        .Select(p => new {key=p.Groups["Name"].Value, val=p.Groups["Age"].Value} )
        .ToList();
    foreach (var r in results)
        Console.WriteLine("Name: \"{0}\", Age: \"{1}\"", r.key, r.val);
}

否则,如果您想使用更加正则表达式的引擎友好模式,请使用具有2个分支的交替,其中两个模式中的任何一个都是强制性的 (以避免空匹配处理):

var strs = new[] { "aaa bbbb; Name=John Lewis; ccc ddd; Age=20;", "AAA bbbb; Age=21;", "Irrelevant", "My Name=Wiktor; no more data" };
var pattern = @"(?:\bName=(?<Name>[^;]+).*?;\s+)?\bAge=(?<Age>\d+)|\bName=(?<Name>[^;]+)(?:.*?;\s+\bAge=(?<Age>\d+))?";
foreach (var str in strs) 
{
    var result = Regex.Match(str, pattern);
    if (result.Success)
    {
        Console.WriteLine("Name: \"{0}\", Age: \"{1}\"", result.Groups["Name"].Value, result.Groups["Age"].Value);
    }
}

请参阅this C# demo

(?:\bName=(?<Name>[^;]+).*?;\s+)?\bAge=(?<Age>\d+)|\bName=(?<Name>[^;]+)(?:.*?;\s+\bAge=(?<Age>\d+))?有2个分支:

  • (?:\bName=(?<Name>[^;]+).*?;\s+)?\bAge=(?<Age>\d+) - Name部分是可选的,Age是强制性的
  • | - 或
  • \bName=(?<Name>[^;]+)(?:.*?;\s+\bAge=(?<Age>\d+))? - Age部分是可选的,Name是强制性的

答案 2 :(得分:0)

...

.*?(?:Name=(?'name'[^;]*);)*.*?(?:Age=(?'age'\d*);)*

答案 3 :(得分:0)

(?'name'\w+)[=]{1}(?'value'[\w ]+)

此正则表达式将为您提供namevalue个群组。在name,您将拥有姓名年龄以及value John Lewis 20

您可以看到how it works here