【问题标题】:Captures count is always zero捕获计数始终为零
【发布时间】:2011-05-29 16:19:08
【问题描述】:

我有一个问题。我使用以下正则表达式:


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 时,循环程序流只是通过它。我调试了Match.Groups["year"] 中没有Captures。所以这是合乎逻辑的行为。但对我来说,我错在哪里并不明显。救命!!

我之前有一个相关的帖子Extract number values enclosed inside curly brackets

谢谢!

编辑。输入样本

Sherwood, reciever, {y:2008,V:5528.35}, {y:2009,V:8653.89}, {y:2010, V:4290.51}
  • 我需要捕获20085528.3520098653.8920104290.51 值并将它们作为命名组进行操作。

2D 编辑

我尝试使用ExplicitCapture 选项和以下表达式:

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

但这并没有帮助。

【问题讨论】:

  • 您能否添加一些您尝试匹配的字符串的示例?
  • Captures.Count 的类型不可为空。你的意思是它为零,或者你在尝试访问它时遇到异常,还是什么?
  • @Ben 我无法成功匹配上一个表达式(在第二次编辑中给出)和输入(第一次编辑)。

标签: c# regex capture


【解决方案1】:

编辑:您可以通过匹配直到下一个逗号的所有内容来简化:[^,]*。这是一个完整的代码 sn-p 以匹配您的源数据:

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

【讨论】:

  • 好的。我明白那个。但这并不能解决有关命名组和捕获它们的问题。
  • 正则表达式在第一个输入字符串时失败。如何检查修复的位置?
【解决方案2】:

我认为问题是逗号:

, \s* \}

哪个应该是可选的(或省略?):

,? \s* \}

【讨论】:

    【解决方案3】:

    阐述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}
    

    【讨论】:

      猜你喜欢
      • 2014-03-22
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      • 2012-01-16
      • 2020-01-07
      • 1970-01-01
      相关资源
      最近更新 更多