我有一堆产品标题,我需要从中提取其中的 SKU。
以下标题为例:
因此,在上述示例中,SKU 分别为
258
、E457
、293A
和 572 C
。
一般来说,SKU要么全是数字(主要是3或4个字符长),要么是字母E后跟3-4个数字,要么是3-4位数字,后跟一个字母,或者一个空格加一个单个字母。
所以我想出了这个模式,它似乎可以很好地识别上述所有情况:
/^E?\d+ ?.?/
https://regex101.com/r/I7kkDP/2
然后,有一些完全混乱的标题,其中的 SKU 位于中间的某个位置...从我所看到的情况来看,这些情况很少见,而且当它们发生时也只是数字,所以没有以 E 开头或以单个字母结尾。以下是两个例子:
2456
55Χ55cm207
45 X 65 厘米幸运的是,在这些罕见情况下,SKU 是标题中遇到的第一个整数。
所以,我需要的是
preg_replace
修复上面完全混乱的标题,这样我的模式就可以正确提取SKU。
提前非常感谢您。
使用单词边界 (
\b
) 将 SKU 与任何其他字符区分开来,然后只需检查您的定义字符。
边界将确保您不会错误地匹配
258 G
与 258 Game of Thrones
。
$rx = '/\bE?\d{3,}( ?[A-Z])?\b/';
if (preg_match($rx, $title, $matches)) {
[ $sku ] = $matches;
}
我可以回答正则表达式模式部分:
(E?\d{3,4} ?[A-Z]?(?=\s))
,在 https://regex101.com 使用以下文本块进行测试:
258 Game of Thrones E457 Pokemon
293A Wool Bed cover 572 C Steel frame whatever
258 Game of Thrones
E457 Pokemon
293A Wool Bed cover
572 C Steel frame whatever
Decorative pillow / Set with bed covers 2456 55Χ55cm
Pillow 207 45 Χ 65 cm
如果您打算用独立的 SKU 代码替换整个产品文本行,则可以使用
preg_replace()
。我将使用富有表现力的变量名称来指示不需要的和想要的子模式意图。
使用
\b(E)?
,以及后来的 (?(2)|(?:\s*[A-Z])?)\b)
是一个条件子模式。如果匹配单独的 E
,则不会匹配任何后缀。如果没有单独的 E
匹配,则可以匹配后缀。
代码:(演示)
$tests = [
'258 Game of Thrones',
'E457 Pokemon',
'293A Wool Bed cover',
'572 C Steel frame whatever',
'Decorative pillow / Set with bed covers 2456 55Χ55cm',
'Pillow 207 45 Χ 65 cm',
'Photo frame 40.4 X 148 cm 888 so nice',
];
$unwantedDimensions = '(?:(?:\d+(?:\.\d+)?\s*[xX]\s*\d+(?:\.\d+)?))';
$capture = '(\b(E)?\d{3,4}(?(2)|(?:\s*[A-Z])?)\b)';
var_export(
preg_replace(
"/(?:$unwantedDimensions|.)*?$capture.*/",
'$1',
$tests
)
);
输出:
array (
0 => '258',
1 => 'E457',
2 => '293A',
3 => '572 C',
4 => '2456',
5 => '207',
6 => '888',
)
或者,如果您希望在产品字符串数组的每个元素上使用
preg_match()
,这里是更改后的脚本:
foreach ($tests as $test) {
var_export(
preg_match(
"/(?:$unwantedDimensions|.)*?\K$capture/",
$test,
$m
) ? $m[0] : 'no match'
);
echo "\n";
}