0

简而言之,我试图匹配符合此模式的字符串中最右边的最长项目:

[0-9][0-9\s]*(\.|,)\s*[0-9]\s*[0-9]

例如,考虑字符串“abc 1.5 28.00”。我想匹配“5 28.00”。

使用“原样”模式,就像这样

preg_match_all('/[0-9][0-9\s]*(\.|,)\s*[0-9]\s*[0-9]/', 'abc 1.5 28.00', $result);

相反,我们得到以下匹配项:

[0] => 1.5 2
[1] => 8.00

出于显而易见的原因,没有“5 28.00”或“28.00”。

我做了一些研究,人们建议对此类问题使用积极的前瞻性。所以我尝试了以下

preg_match_all('/(?=([0-9][0-9\s]*(\.|,)\s*[0-9]\s*[0-9]))/', 'abc 1.5 28.00', $result);

给我们这些比赛:

[0] => 1.5 2
[1] => 5 28.00
[2] => 28.00
[3] => 8.00

现在,“5 28.00”在那里很好,但它不能被可靠地识别为正确的匹配(例如,你不能只是从末端遍历寻找最长的匹配,因为可能会有更长的匹配出现在字符串的前面)。理想情况下,我希望最后的那些子匹配(索引 2 和 3)不存在,这样我们就可以抓住最后一个索引。

有没有人知道如何以最简单/最好的方式完成我所需要的?如果我需要澄清任何事情,请告诉我,因为我知道这些东西会让人感到困惑,在此先感谢。

**编辑:一些额外的输入/匹配示例

"abc 1.5 28.00999" => "5 28.00"(即不能匹配字符串结尾,$)

"abc 500000.05.00" => "5.00"

4

2 回答 2

1

我能为你得到的最近的比赛是以下

((?:\d\s*)+[.,](?:\s*\d){2})(?:(?![.,](?:\s*\d){2}).)*$

并产生以下输出(在每种情况下查看“1”)...

'abc 1.5 28.00999' => array (
  0 => '5 28.00999',
  1 => '5 28.00',
)
'abc 500000.05.00' => array (
  0 => '05.00',
  1 => '05.00',
)
'abc 111.5 8.0c 6' => array (
  0 => '111.5 8.0c 6',
  1 => '111.5 8',
)
'abc 500000.05.0a0' => array (
  0 => '500000.05.0a0',
  1 => '500000.05',
)
'abc 1.5 28.00999 6  0 0.6 6' => array (
  0 => '00999 6  0 0.6 6',
  1 => '00999 6  0 0.6 6',
)
于 2013-04-12T16:19:44.987 回答
1

通过添加美元符号确保您匹配输入字符串的末尾,您的问题很容易解决:

preg_match_all('/[0-9][0-9\s]*(\.|,)\s*[0-9]\s*[0-9]$/', 
               'abc 1.5 28.00', $result);

回报:

array (size=2)
  0 => 
    array (size=1)
      0 => string '5 28.00' (length=7)
  1 => 
    array (size=1)
      0 => string '.' (length=1)

现在我不完全确定您为什么将圆点括在括号中,但据我所知,此输出对于您的问题是正确的,并且实现了“最右边”的要求。

于 2013-04-12T16:15:43.190 回答