Php 子字符串长度的正则表达式
我收到一个由数字和点组成的字符串。我需要这些数字的最小长度为3,所以,我必须在长度较短的数字中添加一个或多个零 例如: 如果我有:Php 子字符串长度的正则表达式,php,regex,string,Php,Regex,String,我收到一个由数字和点组成的字符串。我需要这些数字的最小长度为3,所以,我必须在长度较短的数字中添加一个或多个零 例如: 如果我有: 233.14.205.1.194056.270132 我需要它是: 233.014.205.001.194056.270132 ↑ ↑↑ (注意有14的014和有1的001) 我知道我可以分解字符串,添加所需的零并再次内爆,但我不想创建一个可以用本机函数(preg\u replace)解决的函数,而且我还不太擅长正则表达式。使用explode
233.14.205.1.194056.270132
我需要它是:
233.014.205.001.194056.270132
↑ ↑↑
(注意有14的014
和有1的001
)
我知道我可以分解字符串,添加所需的零并再次内爆,但我不想创建一个可以用本机函数(preg\u replace
)解决的函数,而且我还不太擅长正则表达式。使用explode->zero padding->introde
由于您特别要求采用preg\u 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\u replace
,并在匹配的双位/单位数字之前插入单位或双位零。使用分解->零填充->内爆-/code>确实很简单
由于您特别要求采用preg\u 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
,并在匹配的两位数/一位数之前插入单零或双零。您可能不需要正则表达式,因为您可以通过函数将字符串拆分为一个数组,然后通过和分别填充每个部分最后,使用将所有部件重新装配在一起:
$input = '233.14.205.1.194056.270132';
$output = implode(".",array_map(function($s) { return str_pad($s,3,"0", STR_PAD_LEFT); },explode(".",$input)));
您可能不需要正则表达式,因为您可以通过函数将字符串拆分为一个数组,然后分别通过和填充每个部分,最后使用将所有内容重新组合在一起:
$input = '233.14.205.1.194056.270132';
$output = implode(".",array_map(function($s) { return str_pad($s,3,"0", STR_PAD_LEFT); },explode(".",$input)));
您可以使用以下替换项:
$str = preg_replace('~\.(?!\d{3})|(?=\b\d\b)~', '${0}0', $str);
该模式使用两个分支:
- 第一个匹配一个点,后面不跟3位数字(在这种情况下,替换为点和附加零)
- 第二个仅匹配单个数字之前的位置(在这种情况下,替换为零,因为整个匹配为空)
当已经有两个数字时,只有第一个分支成功,但当只有一个数字时,第一个分支成功,第二个分支在字符串中的下一个位置(紧跟点之后)也成功
请注意,此模式只能用于三位数,不能扩展到更多位数。适用于所需位数的方法可以是:
$str = array_reduce(explode('.', $str), function ($c,$i) {
return sprintf("%s%s%03d", $c, empty($c)?'':'.', $i);
});
或:
您可以使用以下替换项:
$str = preg_replace('~\.(?!\d{3})|(?=\b\d\b)~', '${0}0', $str);
该模式使用两个分支:
- 第一个匹配一个点,后面不跟3位数字(在这种情况下,替换为点和附加零)
- 第二个仅匹配单个数字之前的位置(在这种情况下,替换为零,因为整个匹配为空)
当已经有两个数字时,只有第一个分支成功,但当只有一个数字时,第一个分支成功,第二个分支在字符串中的下一个位置(紧跟点之后)也成功
请注意,此模式只能用于三位数,不能扩展到更多位数。适用于所需位数的方法可以是:
$str = array_reduce(explode('.', $str), function ($c,$i) {
return sprintf("%s%s%03d", $c, empty($c)?'':'.', $i);
});
或:
正则表达式并不适合这样的字符串操作。使用explode()
str\u-pad()
内爆()方法可能会更好。它可能比正则表达式更具可读性和可理解性,正则表达式不适合这样的字符串操作。使用explode()
str\u-pad()
内爆()方法可能会更好。它的可读性和可理解性可能比正则表达式要高得多,因为正则表达式可以实现同样的功能。假设知道字符串,这就否定了这个问题的必要性-也不处理第一组数字可能需要的填充。如果您知道/可以假设这些情况,您可以将零添加到字符串中的正确位置。我觉得这不是一个真正的答案。这就是我要去的地方,但也有一些类似的问题:echo preg\u replace('/\.(\d{0,2})\.+/'.,'.substr('000$1',-3.),'233.14.205.1.194056.270132')代码>(第一组未处理,未在1或2个字符串之间正确填充。假设知道该字符串将否定此问题的必要性-也未处理第一组数字可能需要的填充。如果您知道/可以假设这些情况,您可以将零添加到字符串中的正确位置。不是吗这就是我的方向,但也有一些类似的问题:echo preg\u replace('/\.(\d{0,2})\.+/'.'..substr('000$1',-3.),'233.14.205.1.194056.270132');
(第一组未处理,在1或2个字符串之间填充不正确。可以向上投票几次:)我不认为这可以分两步来做(我可以投几次票。)我不认为这可以分两步来做