使用正则表达式仅匹配第n次出现

时间:2018-02-21 19:47:12

标签: c# regex

我有一个包含3个日期的字符串,如下所示:

XXXXX_20160207_20180208_XXXXXXX_20190408T160742_xxxxx

我想在字符串中选择第二个日期,20180208一个。

是否真的在regex中完成此操作,不得不求助于在代码中拉出2匹配。如果重要,我会使用C#

感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

您可以使用

^(?:[^_]+_){2}(\d+)

然后选择第一组,请参阅a demo on regex101.com

<小时/> 分解,这说

^              # start of the string
(?:[^_]+_){2}  # not _ + _, twice
(\d+)          # capture digits

答案 1 :(得分:0)

试试这个

  

MatchCollection matches = Regex.Matches(sInputLine,@&#34; \ d {8}&#34;);

     

string sSecond = matches [1] .ToString();

答案 2 :(得分:0)

您可以使用正则表达式

^(?:.*?\d{8}_){1}.*?(\d{8})

保存第二个 nd 日期以捕获组1。

Demo

自然地,对于n > 2,将{1}替换为{n-1},以获得第n个 日期。要获取1 st 日期,请使用

^(?:.*?\d{8}_){0}.*?(\d{8})

Demo

C#的正则表达式引擎执行以下操作。

^        # match the beginning of a line
(?:      # begin a non-capture group
  .*?    # match 0+ chars lazily
  \d{8}  # match 8 digits
  _      # match '_'
)        # end non-capture group
{n}      # execute non-capture group n (n >= 0) times
.*?      # match 0+ chars lazily     
(\d{8})  # match 8 digits in capture group 1

要注意的重要一点是,.*?的第一个实例,然后是\d{8},因为它是惰性的,它将吞噬尽可能多的字符,直到接下来的8个字符为数字(并且不能在数字前后加上数字。例如,在字符串

_1234abcd_efghi_123456789_12345678_ABC

(.*?)_\d{8}_中的捕获组1将包含"_1234abcd_efghi_123456789"

答案 3 :(得分:-1)

您可以使用System.Text.RegularExpressions.Regex

请参阅以下示例

Regex regex = new Regex(@"^(?:[^_]+_){2}(\d+)"); //Expression from Jan's answer just showing how to use C# to achieve your goal
GroupCollection groups = regex.Match("XXXXX_20160207_20180208_XXXXXXX_20190408T160742_xxxxx").Groups;
if (groups.Count > 1)
{
    Console.WriteLine(groups[1].Value);
}