A pure-functional solution (mutation-free):
string[] strArray = { "aa", "bb", "xx", "cc", "xx", "dd",
"ee", "ff", "xx", "xx", "gg", "xx" };
var result =
strArray.Aggregate((IEnumerable<IEnumerable<string>>)new IEnumerable<string>[0],
(a, s) => s == "xx" ? a.Concat(new[] { new string[0] })
: a.Any() ? a.Except(new[] { a.Last() })
.Concat(new[] { a.Last().Concat(new[] { s }) }) : a)
.Where(l => l.Any());
// Test
foreach (var i in result)
Console.WriteLine(String.Join(",", i.ToArray()));
If you want to filter out the results past the last marker:
string[] strArray = { "aa", "bb", "xx", "cc", "xx", "dd",
"ee", "ff", "xx", "xx", "gg", "xx"};
var result =
strArray.Aggregate(
new { C = (IEnumerable<string>)null,
L = (IEnumerable<IEnumerable<string>>)new IEnumerable<string>[0] },
(a, s) => s == "xx" ? a.C == null
? new { C = new string[0].AsEnumerable(), a.L }
: new { C = new string[0].AsEnumerable(), L = a.L.Concat(new[] { a.C }) }
: a.C == null ? a : new { C = a.C.Concat(new[] { s }), a.L }).L
.Where(l => l.Any());
// Test
foreach (var i in result)
Console.WriteLine(String.Join(",", i.ToArray()));