簡體   English   中英

如何使用正則表達式找到模式的第N次出現?

[英]How do I find the Nth occurrence of a pattern with 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,並將其應用於任何此類字符串。

請不要提供帶有任何其他c#代碼的解決方案,例如m.Groups[n]Split ,我有意為此要求構建適當的Regex模式。 簡而言之,我無法為每個新的N值修改代碼,我只能修改動態生成的regex表達式,N將作為參數傳遞給方法。 其余所有內容都是靜態的,無法更改。

也許這種表達方式對您有幫助?

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

您將需要根據您的NIe修改{1}

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

您的正則表達式

(\d+)${1}

說要匹配:

  • (\\d+) :匹配1個或多個十進制數字,后跟
  • ${1}匹配原子零寬度斷言“輸入字符串的末尾” 正好一次

應該注意的是, {1} 量詞是多余的,因為通常只有一個輸入字符串結尾(除非您已打開多行選項)。

這就是為什么要匹配“ 273”的原因:這是錨定在字符串末尾的最長數字序列。

您需要使用零寬度的正向后斷言 捕獲字符串中的第N個字段,您需要捕獲在N-1個字段之后的數字字符串。 給定此源字符串:

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

匹配第三個字段的正則表達式,其中第一個字段是1而不是0看起來像這樣:

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

它說

  • 匹配前面的最長數字序列
    • 文字開頭,然后是
    • 一組,由
      • 1個或多個十進制數字,后跟
      • -或文本結尾
    • 該組重復了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

嘗試這個:

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

輸出為15316;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM