如何使用正则表达式找到第N个模式?

时间:2014-03-13 18:06:33

标签: c# regex

我有一串由一些非数字字符分隔的数字,如下所示:" 16-15316-273" 是否有可能以返回第N个匹配组的方式构建正则表达式?我听说${n}可能有所帮助,但至少在这个表达中它对我不起作用:

// Example: I want to get 15316
var r = new Regex(@"(\d+)${1}");
var m = r.Match("16-15316-273");

(\d+)${0}返回16,但是(\d+)${1}给了我273而不是预期的15316

所以N是需要提取的模式的顺序,输入字符串本身(" 16-15316-273"只是一个例子)是动态值,可能在应用程序执行期间发生变化。任务是构建正则表达式,其中唯一改变的是N,并且适用于任何这样的字符串。

请不要提供包含m.Groups[n]Split等其他c#代码的解决方案,我故意要求为此构建正确的正则表达式模式。简而言之,我无法修改每个新N值的代码,我可以修改的是动态构建的正则表达式,N将作为参数传递给方法。其余的都是静态的,无法改变它。

3 个答案:

答案 0 :(得分:3)

也许这个表达会对你有帮助吗?

(?<=(\d+[^\d]+){1})\d+

您需要根据您的N修改{1}。 即。

(?<=(\d+[^\d]+){0})\d+ => 16
(?<=(\d+[^\d]+){1})\d+ => 15316
(?<=(\d+[^\d]+){2})\d+ => 273

答案 1 :(得分:2)

你的正则表达式

(\d+)${1}

说匹配这个:

  • (\d+):匹配1位或更多位小数,后跟
  • ${1}:匹配原子零宽度断言&#34;输入字符串的结尾&#34; 完全一次

应该注意{1} 量词是多余的,因为通常只有一个输入结束字符串(除非你打开了多行)选项)。

这就是为什么你匹配`273&#39;:它是锚定在字符串结尾处的最长数字序列。

您需要使用zero-width positive look-behind assertion。要捕获字符串中的第N个字段,您需要捕获前面有N-1个字段的数字字符串。鉴于此源字符串:

string input = "1-22-333-4444-55555-666666-7777777-88888888-999999999" ;

匹配第3个字段的正则表达式,其中第一个字段为1而不是0,如下所示:

(?<=^(\d+(-|$)){2})\d+

它说

  • 匹配前面的最长数字序列
    • 文字开头,然后是
    • 一组,由...组成
      • 一个或多个十进制数字,后跟
      • -或文字结尾
    • 与该组完全重复2次

这是一个示例程序:

string src = "1-22-333-4444-55555-666666-7777777-88888888-999999999" ;
for ( int n = 1 ; n <= 10  ; ++n )
{
  int n1       = n-1 ;
  string x     = n1.ToString(CultureInfo.InvariantCulture) ;
  string regex = @"(?<=^(\d+(-|$)){"+ x + @"})\d+" ;

  Console.Write( "regex: {0} ",regex);

  Regex rx = new Regex( regex ) ;
  Match m = rx.Match( src ) ;
  Console.WriteLine( "N={0,-2}, N-1={1,-2}, {2}" ,
    n ,
    n1 ,
    m.Success ? "success: " + m.Value : "failure" 
    ) ;
}

它产生这个输出:

regex: (?<=^(\d+(-|$)){0})\d+ N= 1, N-1=0 , success: 1
regex: (?<=^(\d+(-|$)){1})\d+ N= 2, N-1=1 , success: 22
regex: (?<=^(\d+(-|$)){2})\d+ N= 3, N-1=2 , success: 333
regex: (?<=^(\d+(-|$)){3})\d+ N= 4, N-1=3 , success: 4444
regex: (?<=^(\d+(-|$)){4})\d+ N= 5, N-1=4 , success: 55555
regex: (?<=^(\d+(-|$)){5})\d+ N= 6, N-1=5 , success: 666666
regex: (?<=^(\d+(-|$)){6})\d+ N= 7, N-1=6 , success: 7777777
regex: (?<=^(\d+(-|$)){7})\d+ N= 8, N-1=7 , success: 88888888
regex: (?<=^(\d+(-|$)){8})\d+ N= 9, N-1=8 , success: 999999999
regex: (?<=^(\d+(-|$)){9})\d+ N=10, N-1=9 , failure

答案 2 :(得分:0)

试试这个:

string text = "16-15316-273";
Regex r = new Regex(@"\d+");
var m = r.Match(text, text.IndexOf('-'));

输出为15316;)