【问题标题】:c# Regex capturing repeated keyword valuesc# 正则表达式捕获重复的关键字值
【发布时间】:2012-08-15 14:11:46
【问题描述】:

我正在尝试捕获由另一个关键字分隔的关键字的值,或者关键字的行尾可能以任何顺序重复或没有数据可捕获:

关键词: K1,K2

输入数据: somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2

我希望捕获的数据是

1. capturethis1
2. capturethis2
3. capturethis3
4. 
5.

我试过k1|k2(?<Data>.*?)k1|k2,但是捕获的数据总是空的。

谢谢!

【问题讨论】:

    标签: c# regex capture repeat


    【解决方案1】:

    首先,请注意交替运算符| 的优先级较低,因此

    k1|k2(?<Data>.*?)k1|k2
    

    实际上是在寻找k1 或k2(?&lt;Data&gt;.*?)k1 或k2。使用分组:

    (?:k1|k2)(?<Data>.*?)(?:k1|k2)
    

    其次,考虑使用零宽度的lookahead和lookbehind断言:

    (?<=k1|k2)(?<Data>.*?)(?=k1|k2)
    

    【讨论】:

    • 我对其进行了微调,以使最后一个捕获与行尾分隔:(?.*?)(?=k1|k2|$),但除此之外,它就在现场!
    【解决方案2】:

    你在交替的正确轨道上。缺少的部分是使用look-behind 和look-ahead 来断言某些东西必须在分隔符之前和之后。

    (?<=k1|k2)(?<Data>.*?)(?=k1|k2)
    

    Lookbehind (?&lt;=…) 和lookahead (?=…) 是零宽度断言,因此必须满足它们但不要成为匹配的一部分。

    您想要捕获连续分隔符的实例有点棘手,因为您无法真正捕获“无”——两个字符之间的空格。一种方法是捕捉后视(或前瞻):

    (?<=(?<Delimiter>k1|k2))(?<Data>.*?)(?=k1|k2)
    

    这将产生 4 个结果而不是 3 个结果,因为它将在样本数据的末尾包含连续的 k1k2。您只需忽略每场比赛的额外数据 (k1,k2,k2,k1)。

    【讨论】:

      【解决方案3】:
      string s="somedatahereornotk1capturethis1k2capturethis2k2capturethis3k1k2";
      
      Regex r=new Regex("(?<=k1|k2).*?(?=k1|k2)");
      foreach(Match m in r.Matches(s))
      Console.WriteLine(m.Value);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-13
        • 2011-03-11
        • 2017-01-07
        • 2019-12-19
        • 1970-01-01
        • 1970-01-01
        • 2022-11-03
        相关资源
        最近更新 更多