我試圖創建一個用於分割字符串的正則表達式,但不幸的是我的需求比簡單的分割複雜一點,所以我不能在PHP中使用例如preg_split()
。Extraneous Empty Trailing Match
所以我在做什麼是匹配我的分隔符(或者說,它們的一部分)在一個子表達式中,以及它在另一個子表達式中的一切,並且還將字符串的末尾作爲分隔符來處理目的。考慮到這一點,我想出了以下內容:
([^?;]*)(?|\?([0-9]*)|(;)|$)
正如你可以看到希望,第一子圖案查找文本塊沒有分號的任何問號。在此之後,我有一個子模式匹配任何問號和後面的可選數字(存儲),可以是分號(存儲)或字符串結尾。
的問題是,我似乎越來越反對串案件結束外來,空,比賽,像這樣:
$sql = 'CALL foo(?0, ?1, ?2, ?3)';
preg_match_all('/([^?;]*)(?|\?([0-9]*)|(;)|$)/', $sql, $matches);
print_r($matches);
產生輸出看起來像:
Array
(
[0] => Array
(
[0] => CALL insert_host(?0
[1] => , ?1
[2] => , ?2
[3] => , ?3
[4] =>)
[5] =>
)
[1] => Array
(
[0] => CALL insert_host(
[1] => ,
[2] => ,
[3] => ,
[4] =>)
[5] =>
)
[2] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] =>
[5] =>
)
)
注$matches[0][5]
下的空比賽;我希望在匹配括號後能夠滿足字符串大小寫的結尾,導致沒有進一步的匹配,但它繼續產生另一個匹配,我不知道爲什麼。
所以我的問題是,爲什麼會在這裏製作額外的比賽,我該如何防止呢?
注意:我已經考慮要求字符串大小寫的結尾至少有一個字符在它之前,但這是不好的,因爲我實際上想要一個空的結果,如果通配符是在字符串,因爲我試圖模擬分裂函數的行爲。例如,如果輸入是SELECT ?
,我希望匹配SELECT ?
加上一個空字符串。這裏的想法是,一旦我處理了任何匹配的分號,我就可以簡單地使用implode('?', $matches[1])
來重新生成帶有數字通配符的語句。