2016-04-25 114 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