2015-06-02 32 views
0

我有這個PHP正則表達式匹配:PHP不與捕獲組尊重非捕獲組前瞻裏

preg_match_all('/(\d+)(?:\.(?=(\d+)))?/', "43.3", $matches, PREG_SET_ORDER); 

它(至少在MI記)表示:

Match one or more numbers as a group, and if there is a '.' after that 
group followed by a group of numbers, match those too, but ignore the '.'. 

所以,可能的字符串是:

1 
23244 
24.5 
2.454646 

但不是:

1. 

現在,這個工作完美地在regex101.com與任何測試字符串我扔在它,但它似乎並沒有與PHP的工作。這是我所得到的,如果我var_dump($matches)

array(2) { 
    [0]=> 
    array(3) { 
    [0]=> 
    string(3) "43." 
    [1]=> 
    string(2) "43" 
    [2]=> 
    string(1) "3" 
    } 
    [1]=> 
    array(2) { 
    [0]=> 
    string(1) "3" 
    [1]=> 
    string(1) "3" 
    } 
} 
  • 爲什麼我的43後得到點?
  • 爲什麼我將所有東西都重複?
  • 爲什麼我會在第一組中獲得3
+0

我想'$比賽[0] [0]'總是全場比賽,好像你的整個圖案被包裹在一組括號。我不知道如何關閉它。 – mpen

+0

Regex101會爲你解釋:https://regex101.com/r/fO4dM5/1 –

+0

@JaredFarrish考慮到我提到我已經用regex101測試過了,你的評論並沒有真正的幫助。我在這裏問,因爲顯然,regex101給我的解釋(和結果)並不是PHP返回的那些。 – alexandernst

回答

1

第一場比賽總是完全匹配,就好像你的整個模式被包裹在一組圓括號中。我不認爲你可以關閉它。

您在第一組中獲得3,因爲您的模式中有兩個(\d+)。如果您不需要,請從?=之後刪除括號中的括號。

如果你只想充分一些,你可以嘗試這樣的事:

>>> preg_match_all('/(?<!\d)\d+(?:\.\d+)?(?![\d.])/', "43.3 31.52 1.", $matches); 
=> 2 
>>> $matches 
=> [ 
     [ 
      "43.3", 
      "31.52" 
     ] 
    ] 

如果有一個號碼,你應該使用preg_match,不preg_match_all。例如

>>> preg_match_all('/(\d+)(?:\.(\d+))?/', "43.3", $matches) 
=> 1 
>>> $matches 
=> [ 
     [ 
      "43.3" 
     ], 
     [ 
      "43" 
     ], 
     [ 
      "3" 
     ] 
    ] 

您可以隨時取消array_shift的完整匹配。

+1

你的第一個正則表達式就是我從一開始就想實現的。謝謝! – alexandernst

+0

沒有'PREG_SET_ORDER',它確實更好用:-) – mpen

+0

確實!再次感謝您;) – alexandernst

1

兩個子陣列的[0]部分中的值是在每種情況下匹配的整個字符串,然後[1][2]用於捕獲組。

有兩場比賽總體來說,和第一場比賽的全部文本爲43.這是因爲你的正則表達式是說:

  • 匹配一些數字(\d+)
  • 可選匹配由點必須遵循由一些數字(?:\.(?=(\d+)))?

串滿足的43.部分,作爲點後面是3在字符串的末尾。


它不是從問題十分清楚,但它聽起來像是你只是不希望在所有使用超前(?=…)

例如,/(\d+)(?:\.(\d+))?/將爲下列:

// For "43.3" 
array(3) { 
    [0]=> 
    string(4) "43.3" // whole match 
    [1]=> 
    string(2) "43" // first capturing group 
    [2]=> 
    string(1) "3"  // second capturing group 
} 
// For "1." 
array(2) { 
    [0]=> 
    string(1) "1" 
    [1]=> 
    string(1) "1" 
} 
// For "12345" 
array(2) { 
    [0]=> 
    string(5) "12345" 
    [1]=> 
    string(5) "12345" 
} 
+0

謝謝您的解釋。雖然我仍然不確定爲什麼regex101返回的結果不是PHP(即使我在regex101中選擇了PCRE)。 – alexandernst