Регулярное выражение C #: Как извлечь коллекцию - PullRequest
2 голосов
/ 30 сентября 2011

У меня есть коллекция в текстовом файле:

(Collection
  (Item "Name1" 1 2 3)
  (Item "Simple name2" 1 2 3)
  (Item "Just name 3" 4 5 6))

Коллекция также может быть пустой:

(Collection)

Количество предметов не определено. Это может быть один предмет или сто. По предыдущему извлечению у меня уже есть внутренний текст между элементом Collection:

(Item "Name1" 1 2 3)(Item "Simple name2" 1 2 3)(Item "Just name 3" 4 5 6)

В случае пустой коллекции это будет пустая строка.

Как я могу разобрать эту коллекцию, используя регулярное выражение .Net?

Я пробовал это:

string pattern = @"(\(Item\s""(?<Name>.*)""\s(?<Type>.*)\s(?<Length>.*)\s(?<Number>.*))*";

Но приведенный выше код не дает никаких реальных результатов.

UPDATE:

Я пытался использовать регулярные выражения по-другому:

foreach (Match match in Regex.Matches(document, pattern, RegexOptions.Singleline))
{
    for (int i = 0; i < match.Groups["Name"].Captures.Count; i++)
    {
        Console.WriteLine(match.Groups["Name"].Captures[i].Value);
    }
}

или

while (m.Success)
{
    m.Groups["Name"].Value.Dump();
    m.NextMatch();
}

Ответы [ 3 ]

3 голосов
/ 30 сентября 2011

Попробуйте

\(Item (?<part1>\".*?\")\s(?<part2>\d+)\s(?<part3>\d+)\s(?<part4>\d+)\)

это создаст коллекцию матчей:

Regex regex = new Regex(
      "\\(Item (?<part1>\\\".*?\\\")\\s(?<part2>\\d+)\\s(?<part3>\\d"+
      "+)\\s(?<part4>\\d+)\\)",
    RegexOptions.Multiline | RegexOptions.Compiled
    );

//Capture all Matches in the InputText
MatchCollection ms = regex.Matches(InputText);


//Get the names of all the named and numbered capture groups
string[] GroupNames = regex.GetGroupNames();

// Get the numbers of all the named and numbered capture groups
int[] GroupNumbers = regex.GetGroupNumbers();
2 голосов
/ 30 сентября 2011

Я думаю, что вы должны прочитать файл, а затем использовать функцию Sting.Split, чтобы разделить коллекцию и начать читать

   String s = "(Collection
              (Item "Name1" 1 2 3)
              (Item "Simple name2" 1 2 3)
              (Item "Just name 3" 4 5 6))";

   string colection[] = s.Split('(');
   if(colection.Length>1)
   {
      for(i=1;i<colection.Length;i++)
      {
          //process string one by one and add ( if you need it
          //from the last item remove )
      }
   }

это решит проблему легко, нет необходимости накладывать дополнительное бремя на регулярное выражение.

2 голосов
/ 30 сентября 2011

Я думаю, вам может понадобиться сделать ваши снимки нежадными ...

(?<Name>.*?)

вместо

(?<Name>.*)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...