2013-01-10 57 views
0

我在我的文本中用大括號包裹了數字,即{123}{456ABC}。我也有數字不包括括號,即789。我想匹配這些尚未包裹的數字,並使用PHP的preg_replace將它們用英鎊符號包裝,即#789#。數字通常在1-3位數字之間。正則表達式替換爲帶磅符號的包裝數字

print(preg_replace('/\d+/','#$0#', 
'1) I can count to 2997510. You can only count to {456ABC}.')); 

所需的輸出:

#1#) I can count to #2997510#. You can only count to {456ABC}. 

什麼正則表達式將匹配的數字?我試過負先行(?![^\{])\d+[^\{](\d+)[^\{]

+3

[你有什麼嘗試?](http://mattgemmell.com/2008/12/08/what-have-you-tried/) – OmnipotentEntity

+0

'[^ \ {((d +)[^ \ {]'和一些負向預測組合 – skibulk

+0

'(?![^ \ {])\ d +'像這樣一個 – skibulk

回答

0

(\A|[^{\d])(\d[\d\w]*)(\z|[^\}\d\z])應該爲你做。

使用等:

print(preg_replace('/(\A|[^{\d])(\d[\d\w]*)(\z|[^\}\d\z])/','$1#$2#$3', 
'1) I can count to 2997510. You can only count to {456ABC}.')); 

說明:

  • 第一部分(\A|[^{\d])匹配任一輸入端(在字符串的開始捕捉數字)的開始或者非{或數字。這部分確保數字不被包裝。

  • 第二部分(\d[\d\w]*)確實實際匹配了數字。它匹配以數字開頭的任何內容,後跟任意數量的連續數字或字母。

  • 最後部分(\z|[^\}\d\z])類似於第一部分,除了查找輸入的結尾。

  • 由於此正則表達式可以之前和目標號碼之後捕獲一個字符,它的那些字符加回在使用第一和第三匹配子組(如見於PHP例子是重要的。

+0

我正在選擇你的答案,因爲\ A和\ Z的實現非常出色。也用於解釋正則表達式的主題。我想我需要用0美元來替換數字,但是捕獲和加入任何一方的匹配字符都是開箱即用的。我從中學到了很多東西。謝謝! – skibulk

1

[^\{\dA-F]([A-F\d]+)[^\}\dA-F]

(我假設你想用大寫字母匹配十六進制數;如果沒有,只是適當地改變角色職業。)

額外的\d在負面字符類,因爲如果他們不在那裏,那麼引擎將通過切斷最外面的數字來避免括號。例如,[^\{](\d+)[^\}]將匹配{34567}中的456。

該號碼本身就是任何匹配的「組1」。如果你需要自己的整場比賽是數量,使用先行和回顧後:

(?<=[^\{\dA-F])([A-F\d]+)(?=[^\}\dA-F])

這裏是一個Perl樣式的搜索和替換插入#的,沒有超前或回顧後:

s/([^\{\dA-F])([A-F\d]+)([^\}\dA-F])/$1#$2#$3/g

+0

不計算字母字符,即'456ABC'。 – nickb

+0

這是匹配領先的空間和尾隨期:「#2997510.#」 – skibulk

+1

整個事情應該匹配數字中的字符立即左右,是的,但括號將數字分組,所以如果你正在尋找是一場比賽,你可以這樣做。 –