Количество захватов всегда равно нулю - PullRequest
0 голосов
/ 29 мая 2011

У меня проблема. Я использую следующее регулярное выражение:


Pattern =
  (?'name'\w+(?:\w|\s)*), \s*
  (?'category'\w+(?:\w|\s)*), \s*
  (?:
      \{ \s*
          [yY]: (?'year'\d+), \s*
          [vV]: (?'volume'(?:([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))+), \s*
      \} \s*
      ,? \s*
  )*

с опцией IgnorePatternWhitespaces. В моем приложении все выглядело нормально, пока я не отладил его и не столкнулся с проблемой.


var Year = default(UInt32);
// ...
if((Match = Regex.Match(Line, Pattern, Options)).Success)
{
    // Getting Product header information
    Name = Match.Groups["name"].Value;

    // Gathering Product statistics
    for(var ix = default(Int32); ix < Match.Groups["year"].Captures.Count; ix++)
    {
       // never get here
       Year = UInt32.Parse(Match.Groups["year"].Captures[ix].Value, NumberType, Culture);
    }
}

Так в коде выше .. В моем случае совпадение всегда успешно. Я получаю правильное значение для Name, но когда очередь доходит до for цикл программы цикла просто пропускает его. Я отладил, нет Captures в Match.Groups["year"]. Так что это логичное поведение. Но не очевидно для меня, где я ошибаюсь. Помогите !!

Существует предыдущий связанный пост Извлечение числовых значений, заключенных в фигурные скобки Я сделал.

Спасибо!

EDIT. Входные образцы

Sherwood, reciever, {y:2008,V:5528.35}, {y:2009,V:8653.89}, {y:2010, V:4290.51}
  • Мне нужно захватить значения 2008, 5528.35, 2009, 8653.89, 2010, 4290.51 и работать с ними как с именованными группами.

2D РЕДАКТИРОВАНИЕ

Я пытался использовать ExplicitCapture Option и следующее выражение:

(?<name>\w+(w\| )*), (?<category>\w+(w\| )*), (\{[yY]:(?<year>\d+), *[vV]:(?<volume>(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))+)\}(, )?)+

Но это не помогло.

Ответы [ 3 ]

2 голосов
/ 29 мая 2011

Редактировать: Вы можете упростить, сопоставляя все до следующей запятой: [^,]*. Вот полный фрагмент кода, соответствующий вашим исходным данным:

var testRegex = new Regex(@"
    (?'name'[^,]*),\s*
    (?'category'[^,]*),\s*
    ({y:(?'year'[^,]*),\s*
    V:(?'volume'[^,]*),?\s*)*",
    RegexOptions.IgnorePatternWhitespace);
var testMatches = testRegex.Matches(
    "Sherwood, reciev, {y:2008,V:5528.35}, {y:2009,V:8653.89}, {y:2010, V:4290.51}");
foreach (Match testMatch in testMatches)
{
    Console.WriteLine("Name = {0}", testMatch.Groups["name"].Value);
    foreach (var capture in testMatch.Groups["year"].Captures)
        Console.WriteLine("    Year = {0}", capture);
}

Это печатает:

Name = Sherwood
    Year = 2008
    Year = 2009
    Year = 2010
0 голосов
/ 29 мая 2011

Чтобы объяснить, что сказал MRAB:

(?'name'
    \w+
    (?:
       \w|\s
    )*
),
\s* 
(?'category'
     \w+
     (?:
         \w|\s
     )*
),
\s* 
(?:
      \{ 
          \s*
          [yY]:
          (?'year'
               \d+
          ),
          \s*
          [vV]:
          (?'volume'
               (?:
                   (     # Why do you need capturing parenth's here ?
                     [1-9][0-9]*
                     \.?
                     [0-9]*
                   )
                 |
                   (
                     \.[0-9]+
                   )
               )+
          ),        # I'm just guessing this comma doesent match input samples
          \s*
      \}
      \s*
      ,?
      \s*
)*


Sherwood, reciever, {y:2008,V:5528.35}, {y:2009,V:8653.89}, {y:2010, V:4290.51}
0 голосов
/ 29 мая 2011

Я думаю, что проблема в запятой:

, \s* \}

, которая должна быть необязательной (или опущена?):

,? \s* \}
...