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,所以我更愿意将 NxNN*NN * 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',
)