Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何一次选择两个项目?_C#_Regex_Linq - Fatal编程技术网

C# 如何一次选择两个项目?

C# 如何一次选择两个项目?,c#,regex,linq,C#,Regex,Linq,我当时正在使用Regex.Split编写一个PascalCasperser,我希望一次从一个集合中选择两个项目 此示例代码演示 void Main() { string pascalCasedString = "JustLikeYouAndMe"; var words = WordsFromPascalCasedString(pascalCasedString); words.Dump(); } IEnumerable<string> WordsFromPa

我当时正在使用
Regex.Split
编写一个PascalCasperser,我希望一次从一个集合中选择两个项目

此示例代码演示

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?
             ;
}
void Main()
{
string pascalCasedString=“JustLikeYouAndMe”;
var words=WordsFromPascalCasedString(pascalCasedString);
words.Dump();
}
IEnumerable words frompascalcasedstring(string pascalCasedString)
{
var rx=新正则表达式(([A-Z]);
返回rx.Split(PASCALCSEDSTRING)
.Where(c=>!string.IsNullOrEmpty(c))
//如何一次选择2个元素?
;
}
上述代码的结果是:

IEnumerable<String> (10 items)
J 
ust 
L 
ike 
Y 
ou 
A 
nd 
M 
e 
IEnumerable(10项)
J
乌斯特
L
艾克
Y
欧点
A.
钕
M
E
集合的每两个元素生成一个结果,我希望函数
WordsFromPascalCasedString
生成该结果

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

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

Edit对于实际问题,您需要在
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));
var result=Regex.Matches(([A-Z][A-Z]*)([A-Z][A-Z]*)?,“AbCdEfGhIj”)
第()类
.其中(m=>m.Success)
.Select(m=>Tuple.Create(m.Groups[1].Value,m.Groups[2].Value));
就我个人而言,在这种特殊情况下,我会同意西蒙·贝朗格的答案。但一般来说,要从
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]);
}

类似的方法存在于。

中,最简单的方法是编写只返回对的函数

比如:

IEnumerable<Tuple<T,T>> Pairs<T>(IEnumerable<T> items)
{
    T first = default(T);
    bool hasFirst = false;
    foreach(T item in items)
    {
       if (hasFirst)
          yield return Tuple.Create(first, item);
       else
           first = item;
       hasFirst = !hasFirst;
    }
}
奇偶元素(
索引%2==/!=0
)的
Zip
是两行方法。请注意,迭代源集合两次

IEnumerable<Tuple<T,T>> Pairs<T>(IEnumerable<T> collection)
{
  return collection
   .Where((item, index)=>index %2 == 0)
   .Zip(collection.Where((item, index)=>index %2 != 0),
   (first,second)=> Tuple.Create(first,second));
}
IEnumerable对(IEnumerable集合)
{
回收
。其中((项目,索引)=>索引%2==0)
.Zip(集合.其中((项,索引)=>索引%2!=0),
(第一,第二)=>Tuple.Create(第一,第二));
}

这只是为了与大家分享,我在受到其他答案的启发后,提出了一个解决方案。它并不比其他的好

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))
             .InPieces(2)
             .Select(c => c.ElementAt(0) + c.ElementAt(1));
}

static class Ext
{
    public static IEnumerable<IEnumerable<T>> InPieces<T>(this IEnumerable<T> seq, int len)
    {
        if(!seq.Any()) 
            yield break;

        yield return seq.Take(len);

        foreach (var element in InPieces(seq.Skip(len), len))
            yield return element;
    }
}
void Main()
{
string pascalCasedString=“JustLikeYouAndMe”;
var words=WordsFromPascalCasedString(pascalCasedString);
words.Dump();
}
IEnumerable words frompascalcasedstring(string pascalCasedString)
{
var rx=新正则表达式(([A-Z]);
返回rx.Split(PASCALCSEDSTRING)
.Where(c=>!string.IsNullOrEmpty(c))
.输入文件(2)
.选择(c=>c.ElementAt(0)+c.ElementAt(1));
}
静态类扩展
{
公共静态IEnumerable InPieces(此IEnumerable seq,int len)
{
如果(!seq.Any())
屈服断裂;
收益率-收益序列(len);
foreach(输入中的var元素(序列跳过(len),len))
收益-收益要素;
}
}

+1用于解决我的实际问题(谢谢)。。。如果我问的问题得到了答案,我还是会感兴趣的…还有一个问题是什么?是的,我并没有真正尝试去弄清楚解析器,我真的很感兴趣看到其他人想使用linq风格的select,一次处理两个项目。。。但我再次感谢您的帮助这是一个纯粹的娱乐答案-p.s.w.g(+1)已经介绍了创建配对的更好版本。+1我见过许多“批处理”技术,但这是我见过的第一个递归技术。它可能不是最有效率的,但绝对是有创意的。
IEnumerable<Tuple<T,T>> Pairs<T>(IEnumerable<T> collection)
{
  return collection
    .Aggregate(
      Tuple.Create(false, default(T), Enumerable.Empty<Tuple<T,T>>()),
         (accumulate, item)=> !accumulate.Item1 ? 
        Tuple.Create(true, item, accumulate.Item3) :
            Tuple.Create(false, default(T),
              accumulate.Item3.Concat(
                 Enumerable.Repeat(Tuple.Create(accumulate.Item2, item), 1))),
      accumulate => accumulate.Item3); 
}
IEnumerable<Tuple<T,T>> Pairs<T>(IEnumerable<T> collection)
{
  return collection
   .Where((item, index)=>index %2 == 0)
   .Zip(collection.Where((item, index)=>index %2 != 0),
   (first,second)=> Tuple.Create(first,second));
}
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))
             .InPieces(2)
             .Select(c => c.ElementAt(0) + c.ElementAt(1));
}

static class Ext
{
    public static IEnumerable<IEnumerable<T>> InPieces<T>(this IEnumerable<T> seq, int len)
    {
        if(!seq.Any()) 
            yield break;

        yield return seq.Take(len);

        foreach (var element in InPieces(seq.Skip(len), len))
            yield return element;
    }
}