匹配n元组的序列

时间:2015-08-04 18:35:13

标签: c# .net regex

我的以下C#代码返回以下内容:

{(a,b,c),(d,e,f),(r,s,t),(u,v,y)}

{(a,b),(c,d,e)}

{(a,b),(c,d)}

但我不想让{(a,b),(c,d,e)}匹配,因为里面的元组有不同的顺序(分别为2和3)。

private void testwest()
{
    string st = "abc+{(a,b,c),(d,e,f),(r,s+1,t),(u,v,y)}+test-{(a,b),(c,d,e)}+rst+{(a,b),(c,d)}";
    Regex oRegex = new Regex(@"{(\(.*?\),\(.*?\))}");

    foreach (Match mt in oRegex.Matches(st))
    {
        Console.WriteLine(mt.Value);
    }
}

修改 我应该提到n元组的元素可以是任何不包含逗号的文本。我已经编辑了上面的示例字符串,如下面的粗体所示: ABC + {(A,B,C),(d,E,F),(R,的 S + 1 下,T),(U,V,Y)} +测试 - {(一, b),(c,d,e)} + rst + {(a,b),(c,d)}

3 个答案:

答案 0 :(得分:0)

在您决定输出结果之前,您似乎需要评估foreach内的元组以查看它们是否具有相同的长度。

尝试一下:

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

public class Program
{
    public static void Main()
    {
        string st = "abc+{(a,b,c),(d,e,f),(r,s+1,t),(u,v,y)}+test-{(a,b),(c,d,e)}+rst+{(a,b),(c,d)}";
        Regex oRegex = new Regex(@"{(\(.*?\),\(.*?\))}");
        foreach (Match mt in oRegex.Matches(st))
        {
            MatchCollection mCol = Regex.Matches(mt.Value, "\\([^)]+\\)");
            int tupleCount = mCol[0].Value.Split(',').Length;
            if (mCol.Count == mCol.Cast<Match>()
                .Where(m => m.Value.Split(',').Length == tupleCount).Count())
            {
                Console.WriteLine(mt.Value);
            }
        }
    }
}

进入foreach后,我们会执行另一个Regex.Matches()来获取元组。然后,我们会在Linq上执行MatchCollection,以删除不具有与第一个元组相同的元组的元组。这将返回一个临时IEnumerable Count()我们可以与MatchCollection.Count进行比较。如果匹配,则显示Match

结果:

{(a,b,c),(d,e,f),(r,s+1,t),(u,v,y)}
{(a,b),(c,d)}

Fiddle Demo

答案 1 :(得分:0)

我认为不可能仅使用正则表达式来完成此操作。 此代码适用于您的输入。

    static void Main(string[] args)
    {
        string st = "abc+{(a,b,c),(d,e,f),(r,s,t),(u,v,y)}+test-{(a,b),(c,d,e)}+rst+{(a,b),(c,d)}";
        int possibleCountTuple = st.Length / 2;
        for(int i = 1; i<possibleCountTuple; i++)
        {
            TestStringForTuple(st,i);
        }
        Console.ReadLine();
    }

    private static void TestStringForTuple(string str,int order)
    {
        Regex oRegex = new Regex(@"{((.{"+order+"}),(.{"+order+"}))}");
        foreach (Match mt in oRegex.Matches(str))
        {
            Console.WriteLine(mt.Value);
        }
    }

n {order}匹配包含n阶序列的任何字符串。 我不知道这是不是你要找的,但确实有效。

possibleCountTuple只是一个近似值,我知道这几乎不正确,但我想你知道如何处理它

答案 2 :(得分:0)

在匹配其余元素之前,您需要确定第一个元素的顺序。

private void testwest()
{
    string st = "abc+{(a,b,c),(d,e,f),(r,s+1,t),(u,v,y)}+test-{(a,b),(c,d,e)}+rst+{(a,b),(c,d)}";
    Regex oRegex = new Regex(@"{(\([^)]*\)(,\([^)]*\))*)}");

    foreach (Match mt in oRegex.Matches(st))
    {
        int order = mt.Value
            .TakeWhile(ch => ch != ')')
            .Count(ch => ch == ',') + 1;
        var tuplePattern = string.Join(",", Enumerable.Repeat("[^,)]+", order));
        if (Regex.IsMatch(mt.Value, "{\(" + tuplePattern + "\)(,\("+ tuplePattern +"\))*}"))
        {
             Console.WriteLine(mt.Value);
        }
    }
}