PHP正则匹配多格式SKU问题求助
多格式SKU的PHP正则提取方案
问题场景
现有包含多种格式的产品记录,SKU可能包含数字、连字符、斜杠或字母前缀,示例如下:
Name of product 67304-4200-52-21 67304-4200-52 Name of product 67304-4200 Name of product 38927/6437 Name of product BKK1MBM06-02 Name of product BKK1MBM06 Name of product
需要用PHP的preg_match提取其中的SKU,但原有正则无法匹配BKK开头的SKU,需修正正则规则。
原正则问题分析
原正则/\d+\/\d+|\d+-?\d+-?\d+-?\d+|\bbkk.*\b/i存在两个核心问题:
- 针对BKK开头的SKU,
.*\b会贪婪匹配到非SKU内容(比如后续的空格或产品名称片段),因为.*匹配任意字符,直到遇到单词边界,无法精准限制SKU的字符范围。 \b单词边界在连字符与字母/数字之间的判断逻辑,不符合SKU的结构特性,导致匹配失效。
修正后的正则表达式
/(\d+\/\d+|\d+(?:-\d+){1,3}|BKK[A-Za-z0-9-]+)/i
正则各部分说明
\d+\/\d+:匹配斜杠分隔的数字型SKU(如38927/6437)\d+(?:-\d+){1,3}:匹配1-3组连字符分隔的数字SKU(覆盖67304-4200、67304-4200-52、67304-4200-52-21这类格式),使用非捕获组(?:)提升匹配效率BKK[A-Za-z0-9-]+:精准匹配以BKK开头,后续包含字母、数字或连字符的SKU(如BKK1MBM06、BKK1MBM06-02),明确限制SKU的字符范围,避免匹配无关内容
PHP代码示例
$productRecords = [ 'Name of product 67304-4200-52-21', '67304-4200-52 Name of product', '67304-4200 Name of product', '38927/6437 Name of product', 'BKK1MBM06-02 Name of product', 'BKK1MBM06 Name of product' ]; $skuPattern = '/(\d+\/\d+|\d+(?:-\d+){1,3}|BKK[A-Za-z0-9-]+)/i'; foreach ($productRecords as $record) { if (preg_match($skuPattern, $record, $matches)) { echo "提取到SKU:{$matches[1]}\n"; } }
运行后可精准提取所有示例中的SKU,包括BKK开头的格式。
内容的提问来源于stack exchange,提问作者Xander Webb
相关产品推荐
相关产品推荐

