正则表达式子串的长度

时间:2016-04-25 17:28:56

标签: php regex string

我收到一个符合数字和点数的字符串。我需要这些数字的最小长度为3,因此,我必须从长度较短的数字中添加一个或多个零。

示例:

如果我有:

233.14.205.1.194056.270132

我需要它:

233.014.205.001.194056.270132
    ↑       ↑↑

(请注意有014的{​​{1}}和有14的{​​{1}}

我知道我可以爆炸字符串,添加我需要的零并再次内爆它,但我不想为可以用本机函数(001)解决的东西创建一个函数而且我不是很与正则表达式相关(尚)。

3 个答案:

答案 0 :(得分: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,并在匹配的双位/单位数之前插入单位或双位零。

答案 1 :(得分: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);

答案 2 :(得分:0)

您可能不需要正则表达式,因为您只需通过explode()函数将字符串拆分为数组,然后通过array_map()和{{3}填充每个部分然后分别使用str_pad()将所有内容重新组合在一起:

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