2013-04-12 38 views
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’

+0

提供更多的例子輸入字符串和你想要捕獲的內容。 – anubhava

+1

你可以用'[。,]'替換'(\。|,)'' –

+0

謝謝,那很愚蠢。我想我仍然需要逃避。雖然? –

回答

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', 
) 
+0

如此接近!這似乎幾乎全面工作,除了這樣的情況:「abc 111.5 8.0c 6」。在這裏,它應該匹配111.58,但不匹配任何東西。 (如果你刪除了錯誤的「c」,它正確匹配58.06)。 –

+0

@ G.Moore好的,現在呢?還有更多測試用例嗎? –

+0

我覺得這很好!非常感謝你對此的幫助,非常感謝。如果我發現一個不起作用的情況,我會回到這裏,但它應該很好。 –

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) 

現在我不完全知道爲什麼你包裹在括號中的點,但是這個輸出是正確的你的問題,據我所看到的,並實現了「最遠的權利」的規定。

+0

查看我的最新編輯。不幸的是,我們不能依靠期望的匹配作爲字符串的結尾 –

+0

不幸的是,您的編輯只會使標準不太清晰。對於「abc 1.5 28.00999」=>「5 28.00」我不知道它應該如何決定這個結果。你真的需要澄清所需的模式。 –

+0

什麼不清楚?在最基本的層面上,我想要的是符合原始帖子頂部的模式的匹配,並且在搜索字符串中最右邊。更復雜的警告是我想要最長的這樣的字符串,所以在我給出的例子中,而[3] => 8.00是最右邊的匹配,[1] => 5 28.00是最長和最右邊的 –