17

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

[[[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]]] ;

我使用的模式是:

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

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

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

4

4 回答 4

53

使用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]]]

于 2012-12-13T04:30:02.017 回答
7

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

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

在这里看到它。

于 2012-12-12T09:08:41.883 回答
5

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

在 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();
于 2012-12-12T09:13:29.577 回答
4

尝试像这样将 $ 添加到您的模式中\s\[\[(.*?)\]\]\]\;$ ,让我知道它是否有效。

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

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

这转化为:

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

这是 Rubular 示例

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

于 2012-12-12T09:08:18.063 回答