2016-04-25 110 views
0

我收到一個由數字和點符合的字符串。我需要這些數字的最小長度爲3,因此,我必須在長度較小的數字中添加一個或多個零。子串長度的正則表達式

例子:

如果我有:

233.14.205.1.194056.270132 

我需要它是:

233.014.205.001.194056.270132 
    ↑  ↑↑ 

(注意014那裏是一個14和那裏有一個的0011

我知道我可以爆炸字符串,添加我需要的零並再次崩潰,但我不想創建一個可以使用本地函數解決的函數(preg_replace),而我對於正則表達式(還不是很好) 。

+3

正則表達式是不是真的要來適合字符串操作是這樣的。使用'explode()'>'str_pad()'>'implode()'方法可能會更好。它可能會比可以完成相同的正則表達式更具可讀性和可理解性。 –

回答

1

使用explode -> zero padding -> implode確實很簡單。

既然你是專門詢問這裏做的preg_replace事情是這樣的:

$s = '233.14.205.1.194056.270132' 

$repl = preg_replace(array('/\b\d\b/', '/\b\d\d\b/'), array('00$0', '0$0'), $s); 
//=> 233.014.205.001.194056.270132 

這裏,我們通過正則表達式的2元件陣列preg_replace和匹配的雙前插入燒毛或雙零/單個數字。

+0

假定字符串的知識會否定這個問題的必要性 - 也不處理第一組數字所需的可能填充。如果你知道/可以承擔這些事情,你可以添加零到字符串中的正確位置。對我來說,這不是一個真正的答案。這是我前往的地方,但也有類似的問題:'echo preg_replace('/ \。(\ d {0,2})\。+ /','。'。substr('000 $ 1',-3)。 '。','233.14.205.1.194056.270132');'(第一組沒有處理,在1或2個字符串之間填充得不好, – pherris

0

你可能並不需要爲這個正則表達式,你可以簡單的字符串通過explode()功能每個部分通過array_map()str_pad()分別分成數組,然後墊然後最後用implode(),以適應一切重新走到一起:

$input = '233.14.205.1.194056.270132'; 
$output = implode(".",array_map(function($s) { return str_pad($s,3,"0", STR_PAD_LEFT); },explode(".",$input))); 
1

您可以使用此替代:

$str = preg_replace('~\.(?!\d{3})|(?=\b\d\b)~', '${0}0', $str); 

demo

模式使用兩個分支:

  • 第一匹配不後跟3個數字的點(在此情況下,替換是點和附加的零)
  • 第二匹配僅前的位置單個數字(在這種情況下,由於整個比賽是空的,所以替換僅爲零)。

當已經有兩個數字,只有第一支成功,但當時只有有一個數字的第一支成功和第二支在字符串(點之後)的下一個位置成功過

請注意,您只能對三位數字使用此模式,您無法將其擴展爲更多數字。對於您希望能夠位數工作的方式:

$str = array_reduce(explode('.', $str), function ($c,$i) { 
    return sprintf("%s%s%03d", $c, empty($c)?'':'.', $i); 
}); 

或:

$str = preg_replace_callback('~\b\d{1,2}\b~', function ($m) { 
    return sprintf("%03d", $m[0]); 
}, $str); 
+1

就可以了,贊成幾次:)我沒有想到它可能會完成分兩步進行 – splash58