PHP REGEX:如何在字符串的 middle/end 中填充数字
PHP REGEX: how to pad numbers in the middle/end of a string
我有一个来自 JSON squirt 的键=>值对列表。我对数组进行了排序,剩下以下内容(摘录相关案例,因为它们高达 92):
dir1summary
dir10summary
dir1summarydue
dir10summarydue
directive1
directive10
directivecode1
directivecode10
我需要做的是:
1)将所有数字放在最后
2) 将它们填充到 2 位数 (01,02,&c)
所以列表最终看起来像这样:
directivesummary01
directivesummary10
directivesummarydue01
directivesummarydue10
directive01
directive10
directivecode01
directivecode10
鉴于键名明显相似,我希望用一个 REGEX 语句来做到这一点,但我迷路了。这是我目前所拥有的:
dir((\d{1,2}(summary|summarydue))|((ective\d{1,2})|(ectivecode\d{1,2})))
...aaa 我不知道下一步该做什么。如何继续前进?有更好的 compact 方法吗?
编辑:这也意味着我必须用 'directive' 替换 'dir'。它隐含在结果列表中,但我没有为它制作一个项目符号。此外,REGEX 是我在 RegExer 时能够构建的全部内容。因此 "lost what to do next" 部分。
- 匹配但不捕获
dir
- 匹配但不捕获可选子字符串
ective
- 在
ective
之后立即保留零个或多个非数字字符作为捕获组 #1(这考虑了可选的子字符串,例如 summarydue
)
- 保留整个整数作为捕获组#2
- 保留字符串的其余部分作为捕获组 #3
- 在自定义函数中,硬编码
directive
,然后追加捕获组#1(可能为空),然后捕获组#3(也可能为空),最后留下填充捕获组#2零到最大长度为 2 位数字并将该值附加到字符串的末尾
代码:(Demo)
$strings = [
'dir1summary',
'dir10summary',
'dir1summarydue',
'dir10summarydue',
'directive1',
'directive10',
'directivecode1',
'directivecode10',
];
var_export(
preg_replace_callback(
'/dir(?:ective)?(\D*)(\d+)(.*)/',
function ($m) {
return "directive{$m[1]}{$m[3]}" . str_pad($m[2], 2, "0", STR_PAD_LEFT);
},
$strings
)
);
输出:
array (
0 => 'directivesummary01',
1 => 'directivesummary10',
2 => 'directivesummarydue01',
3 => 'directivesummarydue10',
4 => 'directive01',
5 => 'directive10',
6 => 'directivecode01',
7 => 'directivecode10',
)
或者,您可以使用 sscanf()
解析字符串,然后使用 printf()
.
以所需格式打印隔离的组件
代码:(Demo)
foreach ($strings as $string) {
sscanf($string, '%[^0-9]%d%s', $dir, $num, $str);
printf("%s%s%02d\n", str_pad($dir, 9, 'ective'), $str, $num);
}
// same result strings as above
我有一个来自 JSON squirt 的键=>值对列表。我对数组进行了排序,剩下以下内容(摘录相关案例,因为它们高达 92):
dir1summary
dir10summary
dir1summarydue
dir10summarydue
directive1
directive10
directivecode1
directivecode10
我需要做的是: 1)将所有数字放在最后 2) 将它们填充到 2 位数 (01,02,&c) 所以列表最终看起来像这样:
directivesummary01
directivesummary10
directivesummarydue01
directivesummarydue10
directive01
directive10
directivecode01
directivecode10
鉴于键名明显相似,我希望用一个 REGEX 语句来做到这一点,但我迷路了。这是我目前所拥有的:
dir((\d{1,2}(summary|summarydue))|((ective\d{1,2})|(ectivecode\d{1,2})))
...aaa 我不知道下一步该做什么。如何继续前进?有更好的 compact 方法吗?
编辑:这也意味着我必须用 'directive' 替换 'dir'。它隐含在结果列表中,但我没有为它制作一个项目符号。此外,REGEX 是我在 RegExer 时能够构建的全部内容。因此 "lost what to do next" 部分。
- 匹配但不捕获
dir
- 匹配但不捕获可选子字符串
ective
- 在
ective
之后立即保留零个或多个非数字字符作为捕获组 #1(这考虑了可选的子字符串,例如summarydue
) - 保留整个整数作为捕获组#2
- 保留字符串的其余部分作为捕获组 #3
- 在自定义函数中,硬编码
directive
,然后追加捕获组#1(可能为空),然后捕获组#3(也可能为空),最后留下填充捕获组#2零到最大长度为 2 位数字并将该值附加到字符串的末尾
代码:(Demo)
$strings = [
'dir1summary',
'dir10summary',
'dir1summarydue',
'dir10summarydue',
'directive1',
'directive10',
'directivecode1',
'directivecode10',
];
var_export(
preg_replace_callback(
'/dir(?:ective)?(\D*)(\d+)(.*)/',
function ($m) {
return "directive{$m[1]}{$m[3]}" . str_pad($m[2], 2, "0", STR_PAD_LEFT);
},
$strings
)
);
输出:
array (
0 => 'directivesummary01',
1 => 'directivesummary10',
2 => 'directivesummarydue01',
3 => 'directivesummarydue10',
4 => 'directive01',
5 => 'directive10',
6 => 'directivecode01',
7 => 'directivecode10',
)
或者,您可以使用 sscanf()
解析字符串,然后使用 printf()
.
代码:(Demo)
foreach ($strings as $string) {
sscanf($string, '%[^0-9]%d%s', $dir, $num, $str);
printf("%s%s%02d\n", str_pad($dir, 9, 'ective'), $str, $num);
}
// same result strings as above