【问题标题】:Regex get last occurrence of the pattern正则表达式获取模式的最后一次出现
【发布时间】:2012-12-12 08:59:54
【问题描述】:

我有一个字符串,我需要选择模式的最后一次出现。 字符串是:

[[[1302638400000.0, 0], [1302724800000.0, 610.64999999999998], [1302811200000.0, 2266.6500000000001], [1303156800000.0, 4916.9300000000003], [1303329600000.0, 6107.3199999999997], [1303934400000.0, 9114.6700000000001]], [[1302638400000.0, 20000.0], [1302724800000.0, 20000.0], [1302811200000.0, 20000.0], [1303156800000.0, 20000.0], [1303329600000.0, 20000.0], [1303934400000.0, 20000.0]], [[1302638400000.0, 20000.0], [1302724800000.0, 20610.650000000001], [1302811200000.0, 22266.650000000001],[1303156800000.0,24916.93],[1303329600000.0,26107.32],[1303934400000.0,29114.669999999998],[1304452800000.0,30078.23]]的 [[1302718580000.0,0.0],[1302772440000.0,3.0532500000000073],[1303107093000.0,11.333250000000007] [1303107102000.0, 21.753250000000008], [1303352295000.0, 24.584650000000003], [1303352311000.0, 26.8766], [1303815010000.0, 30.536599999999996], [1303815028000.0, 27.703349999999993]p>];

我使用的模式是:

\s\[\[(.*?)\]\]

不幸的是,它只选择了第一次出现。突出显示的文本是所需的结果。最后有多少个方括号无所谓,只需要最后一个数组集即可。

更新: 如果它可以帮助你,那么编码是在c#中

【问题讨论】:

    标签: c# .net regex


    【解决方案1】:

    使用RightToLeft 选项:

    Regex.Match(s, @"\[\[(.*?)\]\]", RegexOptions.RightToLeft)
    

    此选项是 .NET 正则表达式独有的,并且完全符合您的要求:从输入的末尾而不是开头进行搜索。特别值得注意的是,非贪婪的? 修饰符的工作方式与您预期的一样;如果你把它关掉,你会得到整个输入,但有了它你会得到:

    [[1302718580000.0, 0.0], [1302772440000.0, 3.0532500000000073], [1303107093000.0, 11.333250000000007], [1303107102000.0, 21.753250000000008], [1303352295000.0, 24.584650000000003], [1303352311000.0, 26.8766], [1303815010000.0, 30.536599999999996], [1303815028000.0, 27.703349999999993]]]

    【讨论】:

    • 如此简单,却又如此未知。 @Harry 这是 Stack Overflow 上最常见的问题。
    【解决方案2】:

    对最后一组[[进行贪婪匹配并捕获..

    .*(\[\[.*\]\])\];
    

    here

    【讨论】:

    • 看起来它适用于 Ruby。我正在使用 c#,我正在使用不同的网站来检查正则表达式:regexr.com?334dc,不幸的是它选择了整个字符串
    • 正则表达式匹配整个字符串,但您感兴趣的部分被捕获在组 #1 中(在 C# 中,您将使用 'Group[1].Value` 来提取它)。正如我的回答所解释的那样,这种技术适用于各种风格,但 .NET 也提供了一个更简洁的选择。
    • @AlanMoore 是正确的,通常这是无法指定出现的唯一方法(这是特定于语言的)。由于该问题未提及C#,因此我只能提供最佳的语言无关解决方案,因此请务必在问题中添加所有相关信息。 +1 RightToLeft
    【解决方案3】:

    应该有一个全局标志或一个方法来返回您的语言中的所有匹配项。使用它并进行最后一场比赛。

    在 C# 中,Matches() 返回一个包含所有找到的匹配项的 MatchCollection。所以你可以这样做:

    string source = "[[[1302638400000.0, 0], [1302724800000.0, 610.64999999999998], [1302811200000.0, 2266.6500000000001], [1303156800000.0, 4916.9300000000003], [1303329600000.0, 6107.3199999999997], [1303934400000.0, 9114.6700000000001]], [[1302638400000.0, 20000.0], [1302724800000.0, 20000.0], [1302811200000.0, 20000.0], [1303156800000.0, 20000.0], [1303329600000.0, 20000.0], [1303934400000.0, 20000.0]], [[1302638400000.0, 20000.0], [1302724800000.0, 20610.650000000001], [1302811200000.0, 22266.650000000001], [1303156800000.0, 24916.93], [1303329600000.0, 26107.32], [1303934400000.0, 29114.669999999998], [1304452800000.0, 30078.23]], [[1302718580000.0, 0.0], [1302772440000.0, 3.0532500000000073], [1303107093000.0, 11.333250000000007], [1303107102000.0, 21.753250000000008], [1303352295000.0, 24.584650000000003], [1303352311000.0, 26.8766], [1303815010000.0, 30.536599999999996], [1303815028000.0, 27.703349999999993]]];";
    Regex r = new Regex(@"\s\[\[(.*?)\]\]");
    
    MatchCollection result = r.Matches(source);
    
    if (result.Count > 0) {
        Console.WriteLine(result[result.Count - 1]);
    } else {
        Console.WriteLine("No match found!");
    }
    Console.ReadLine();
    

    【讨论】:

    • @user1333853,我添加了一个C#解决方案
    【解决方案4】:

    尝试像 \s\[\[(.*?)\]\]\]\;$ 那样将 $ 添加到您的模式中,如果可行,请告诉我。

    目前我手头没有 bash,所以我无法检查,但它应该可以解决问题。

    编辑:正确的版本\S+\s?+(?!((.*\[\[)))

    翻译成:

    \S   : all alfanumeric
    \s?  : all 1 space occurences
    ?!   : not 
    .*   : everything
    \[\[ : until the last pattern of [[ (excluded)
    

    Here is the Rubular example

    顺便说一句,很棒的工具 rubular,让我想更多地研究 ruby​​ 和正则表达式:D

    【讨论】:

    • 是的,在 ti unescape the ";" 之后想到了
    • 仍然超过匹配项,并且不需要检查 bash,因为存在许多站点,例如 rubular.com
    • 不,这个选择从第一次出现在 [[
    • 从文件名中删除路径名:.*\([A-Za-z0-9_$.]+)$
    猜你喜欢
    • 2021-01-02
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    相关资源
    最近更新 更多