PHP 将 N*N 和 NxN 等维度转换为 N x N 的正则表达式
PHP regex to convert dimensions like N*N and NxN into N x N
我有一系列用户输入的搜索词,以不同的方式询问同样的事情。例如,有人正在搜索框架 8 x 10 frame
。他们经常通过以下方式搜索:
8x10 frame
8*10 frame
8 * 10 frame
8 x 10 frame
8x10 photo frame
在文体上,我更喜欢 N x N
,所以我更愿意将 NxN
、N*N
、N * N
的所有变体转换为 N x N
。
示例:
8x10 frame
-> 8 x 10 frame
8*10 frame
-> 8 x 10 frame
8x10 photo frame
-> 8 x 10 photo frame
我试过使用 str_replace,但是 if-else 条件太多了,我的代码变得难以管理。我觉得我不是第一个遇到这个问题的人,希望有一些不错的正则表达式或内置函数存在。
编辑:我以“8 x 10”为例,但我们需要考虑任何自定义组合,如“4 x 3”、“12 x 4”等。
使用 str_replace
似乎效果很好。如果您需要完成大量转换,那么多写几行代码来构建查找和更改数组将非常容易。
$data = ['8x10 frame','8*10 frame','8 * 10 frame','8 x 10 frame','8x10 photo frame'];
$look4 = ['*','8*' ,'8x' ,'x10',' '];
$change2 = ['x','8 *','8 x','x 10',' '];
foreach ($data as $entry) {
echo '*' . $entry . '* -> *' . str_replace($look4,$change2,$entry) . '*' . PHP_EOL;
}
使用正则表达式,您可以使用...
echo preg_replace("/(\d+)\s*[Xx\*]\s*(\d+)/", " x ", $a);
模式是
(\d+) - Any number of digits
\s* - 0 or more spaces
[Xx\*] - either X, x or *
\s* - 0 or more spaces
(\d+) - Any number of digits
它被替换为 " x "
,所以这给出了一致的输出。
匹配一个数字,然后是零或一个 space,然后是 x
或 *
,然后是零或一个 space,然后是一个数字。
如果您希望“零个或多个”而不是“零个或一个”,请将 ?
替换为 *
。
\K
重新开始全字符串匹配——所以它“忘记”了第一个匹配的数字。
“先行”确保找到维度分隔符之后的数字但不包括在全字符串匹配中。
使用 i
模式修饰符意味着匹配不区分大小写。
使用此模式,您无需费心捕获整数序列,并且您的替换字符串更易于阅读。
字符 class 内的 *
永远不需要转义。
代码:(Demo)
$strings = [
'8x10 frame',
'8*10 frame',
'8 * 10 frame',
'8 x 10 frame',
'8x10 photo frame'
];
var_export(preg_replace('~\d\K ?[x*] ?(?=\d)~i', ' x ', $strings));
输出:
array (
0 => '8 x 10 frame',
1 => '8 x 10 frame',
2 => '8 x 10 frame',
3 => '8 x 10 frame',
4 => '8 x 10 photo frame',
)
我有一系列用户输入的搜索词,以不同的方式询问同样的事情。例如,有人正在搜索框架 8 x 10 frame
。他们经常通过以下方式搜索:
8x10 frame
8*10 frame
8 * 10 frame
8 x 10 frame
8x10 photo frame
在文体上,我更喜欢 N x N
,所以我更愿意将 NxN
、N*N
、N * N
的所有变体转换为 N x N
。
示例:
8x10 frame
-> 8 x 10 frame
8*10 frame
-> 8 x 10 frame
8x10 photo frame
-> 8 x 10 photo frame
我试过使用 str_replace,但是 if-else 条件太多了,我的代码变得难以管理。我觉得我不是第一个遇到这个问题的人,希望有一些不错的正则表达式或内置函数存在。
编辑:我以“8 x 10”为例,但我们需要考虑任何自定义组合,如“4 x 3”、“12 x 4”等。
使用 str_replace
似乎效果很好。如果您需要完成大量转换,那么多写几行代码来构建查找和更改数组将非常容易。
$data = ['8x10 frame','8*10 frame','8 * 10 frame','8 x 10 frame','8x10 photo frame'];
$look4 = ['*','8*' ,'8x' ,'x10',' '];
$change2 = ['x','8 *','8 x','x 10',' '];
foreach ($data as $entry) {
echo '*' . $entry . '* -> *' . str_replace($look4,$change2,$entry) . '*' . PHP_EOL;
}
使用正则表达式,您可以使用...
echo preg_replace("/(\d+)\s*[Xx\*]\s*(\d+)/", " x ", $a);
模式是
(\d+) - Any number of digits
\s* - 0 or more spaces
[Xx\*] - either X, x or *
\s* - 0 or more spaces
(\d+) - Any number of digits
它被替换为 " x "
,所以这给出了一致的输出。
匹配一个数字,然后是零或一个 space,然后是 x
或 *
,然后是零或一个 space,然后是一个数字。
如果您希望“零个或多个”而不是“零个或一个”,请将 ?
替换为 *
。
\K
重新开始全字符串匹配——所以它“忘记”了第一个匹配的数字。
“先行”确保找到维度分隔符之后的数字但不包括在全字符串匹配中。
使用 i
模式修饰符意味着匹配不区分大小写。
使用此模式,您无需费心捕获整数序列,并且您的替换字符串更易于阅读。
字符 class 内的 *
永远不需要转义。
代码:(Demo)
$strings = [
'8x10 frame',
'8*10 frame',
'8 * 10 frame',
'8 x 10 frame',
'8x10 photo frame'
];
var_export(preg_replace('~\d\K ?[x*] ?(?=\d)~i', ' x ', $strings));
输出:
array (
0 => '8 x 10 frame',
1 => '8 x 10 frame',
2 => '8 x 10 frame',
3 => '8 x 10 frame',
4 => '8 x 10 photo frame',
)