使用C#中的正则表达式和lambda将复杂字符串拆分为类列表

时间:2013-04-18 08:13:11

标签: c# regex lambda

给定字符串“a:b,c”,我想在C#中使用正则表达式和lambda表达式将字符串拆分为类列表,以便返回以下内容。

{
    Column1: "a",
    Column2: "b",
},
{
    Column1: "a",
    Column2: "c",
}

换句话说,我想在冒号后面为冒号后面的每个逗号分隔值重复该值。在SQL中,这相当于进行交叉连接,其中Column1是连接的左侧,Column2是右侧。

我有大部分代码,包括正则表达式,但我无法让第二个select将逗号分隔值的split投影到新类中。相反,我的代码有效地返回以下内容。

{
    Column1: "a",
    Column2: [
        "b",
        "c"
    ]
}

这是我现在的代码。

public class MyClass {
    public string Column1 { get; set; }
    public string Column2 { get; set; }
}

List<MyClass> mc = "a:b,c"
    .Select(a => new { Column1 = new Regex(@"[a-z]+(?=\:)").Match(a).Value), Column2s = new Regex(@"(?<=\:)[a-z]+(,[a-z]+)*").Match(a).Value })
    .Select(b => new MyClass { Column1 = b.Column1, Column2 = b.Column2s.Split(',') })
    .ToList();

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

string input = "a:b,c";

int colon = input.IndexOf(':');
string left = input.Substring(0, colon);
string right = input.Substring(colon + 1);

List<MyClass> result = right.Split(',')
                            .Select(x => new MyClass
                            {
                                Column1 = left,
                                Column2 = x,
                            })
                            .ToList();

答案 1 :(得分:0)

肯定存在其他问题的解决方法。你可以尝试这个:

    [Test]
    public void ATest()
    {
        const string TestValue = "a:b,c";

        string valueForColumnA = new Regex(@"[a-z]+(?=\:)").Match(TestValue).Value;
        string setForColumnB = new Regex(@"(?<=\:)[a-z]+(,[a-z]+)*").Match(TestValue).Value;
        var target = setForColumnB.Split(',')
            .Select(item => new MyClass { Column1 = valueForColumnA, Column2 = item })
            .ToList();

        Assert.AreEqual(target[0].Column1, "a");
        Assert.AreEqual(target[0].Column2, "b");

        Assert.AreEqual(target[1].Column1, "a");
        Assert.AreEqual(target[1].Column2, "c");
    }

可能是不使用正则表达式(在性能方面)更好的解决方案,但是,如果您将此指定为要求,则此解决方案可以正常工作。