Это моя исходная строка:
<box><3>
<table><1>
<chair><8>
Это мой Regex Patern:
<(?<item>\w+?)><(?<count>\d+?)>
Это мой класс Item
class Item
{
string Name;
int count;
//(...)
}
Это моя коллекция предметов;
List<Item> OrderList = new List(Item);
Я хочу заполнить этот список с помощью элемента, основанного на исходной строке. Это моя функция. Он не работает.
Regex ItemRegex = new Regex(@"<(?<item>\w+?)><(?<count>\d+?)>", RegexOptions.Compiled);
foreach (Match ItemMatch in ItemRegex.Matches(sourceString))
{
Item temp = new Item(ItemMatch.Groups["item"].ToString(), int.Parse(ItemMatch.Groups["count"].ToString()));
OrderList.Add(temp);
}
Возможно, некоторые небольшие ошибки, такие как пропуская букву, это пример, потому что это более простая версия того, что у меня есть в моем приложении.
Проблема в том, что в итоге у меня есть только один элемент в OrderList.
UPDATE
Я заработал. Thans for help.
class Program
{
static void Main(string[] args)
{
string sourceString = @"<box><3>
<table><1>
<chair><8>";
Regex ItemRegex = new Regex(@"<(?<item>\w+?)><(?<count>\d+?)>", RegexOptions.Compiled);
foreach (Match ItemMatch in ItemRegex.Matches(sourceString))
{
Console.WriteLine(ItemMatch);
}
Console.ReadLine();
}
}
Возвращает 3 матча для меня. Ваша проблема должна быть в другом месте.
В будущем я хочу документировать приведенный выше код, преобразованный в использование декларативного подхода в качестве фрагмента кода LinqPad:
var sourceString = @"<box><3>
<table><1>
<chair><8>";
var count = 0;
var ItemRegex = new Regex(@"<(?<item>[^>]+)><(?<count>[^>]*)>", RegexOptions.Compiled);
var OrderList = ItemRegex.Matches(sourceString)
.Cast<Match>()
.Select(m => new
{
Name = m.Groups["item"].ToString(),
Count = int.TryParse(m.Groups["count"].ToString(), out count) ? count : 0,
})
.ToList();
OrderList.Dump();
С выходом:
Чтобы решить только заголовок вопроса ( "циклическое совпадение с регулярными выражениями" ), вы можете:
var lookfor = @"something (with) multiple (pattern) (groups)";
var found = Regex.Matches(source, lookfor, regexoptions);
var captured = found
// linq-ify into list
.Cast<Match>()
// flatten to single list
.SelectMany(o =>
// linq-ify
o.Groups.Cast<Capture>()
// don't need the pattern
.Skip(1)
// select what you wanted
.Select(c => c.Value));
Это "сгладит" все зафиксированные значения до одного списка. Чтобы сохранить группы захвата, используйте Select
, а не SelectMany
, чтобы получить список списков.