如何一次选择2个项目?

Aar*_*ide 4 c# regex linq

我正在编写PascalCaseParser Regex.Split,我希望一次从一个集合中选择两个项目.

此示例代码演示.

void Main()
{
    string pascalCasedString = "JustLikeYouAndMe";
    var words = WordsFromPascalCasedString(pascalCasedString);
    words.Dump();
}

IEnumerable<string> WordsFromPascalCasedString(string pascalCasedString)
{
    var rx = new Regex("([A-Z])");
    return rx.Split(pascalCasedString)
             .Where(c => !string.IsNullOrEmpty(c))
             // how to select 2 elements at a time?
             ;
}
Run Code Online (Sandbox Code Playgroud)

上面代码的结果是:

IEnumerable<String> (10 items)
J 
ust 
L 
ike 
Y 
ou 
A 
nd 
M 
e 
Run Code Online (Sandbox Code Playgroud)

集合中的每两个元素都会产生一个我希望函数WordsFromPascalCasedString产生的结果.

我的问题是:一般来说,您如何处理一次返回两件物品的要求.我很好奇是否有任何有趣的非暴力方法.

Sim*_*ger 5

正则表达式应该是([A-Z][a-z]*).如果要包含数字,请调整最后一部分.如果您希望在大写分隔符后面至少有一个小写元素,请使用+而不是*.

编辑对于实际问题,您需要实现并迭代for循环以获得更好的性能(将列表传递一次).在您的具体问题中,您可以使用Regex.Matches

var result = Regex.Matches("([A-Z][a-z]*)([A-Z][a-z]*)?", "AbCdEfGhIj")
                  .OfType<Match>()
                  .Where(m => m.Success)
                  .Select(m => Tuple.Create(m.Groups[1].Value, m.Groups[2].Value));
Run Code Online (Sandbox Code Playgroud)


p.s*_*w.g 5

就个人而言,在这个特殊情况下,我会选择Simon Belanger的答案.但一般来说,要从a中选择连续对IEnumerable,你可以使用:

IEnumerable<Tuple<string, string>> WordsFromPascalCasedString(string pascalCasedString)
{
    var rx = new Regex("([A-Z])");
    var array = rx.Split(pascalCasedString)
                  .Where(c => !string.IsNullOrEmpty(c))
                  .ToArray();
    var items = Enumerable.Range(0, array.Length / 2)
                          .Select(i => Tuple.Create(array[i * 2], array[i * 2 + 1]);
}
Run Code Online (Sandbox Code Playgroud)

或者这需要更多努力,但它可以重复使用并且更有效:

IEnumerable<Tuple<T, T>> Pairs<T>(IEnumerable<T> input)
{
    var array = new T[2];
    int i = 0;
    foreach(var x in input)
    {
        array[i] = x;
        i = (i + 1) % 2;
        if (i == 0)
        {
            yield return Tuple.Create(array[0], array[1]);
        }
    }
}


IEnumerable<Tuple<string, string>> WordsFromPascalCasedString(string pascalCasedString)
{
    var rx = new Regex("([A-Z])");
    var output = rx.Split(pascalCasedString)
                   .Where(c => !string.IsNullOrEmpty(c));
    var items = Pairs(output);
}
Run Code Online (Sandbox Code Playgroud)

它可以很容易地扩展到以下组n:

IEnumerable<IEnumerable<T>> Batches<T>(IEnumerable<T> input, int n)
{
    var array = new T[n];
    int i = 0;
    foreach(var x in input)
    {
        array[i] = x;
        i = (i + 1) % n;
        if (i == 0)
        {
            yield return array.ToArray();
        }
    }

    if (i != 0)
    {
        yield return array.Take(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

存在类似的方法MoreLINQ.