Regex правильно распознает SKU в заголовке с учетом некоторых определенных правил

У меня есть куча названий продуктов, из которых мне нужно извлечь SKU, который в них содержится.

В качестве примера возьмем следующие заголовки:

  • 258 Игра престолов
  • E457 Покемон
  • 293A Шерстяное покрывало
  • 572 C Стальная рама какая угодно

Таким образом, в приведенных выше примерах 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Х55см
  • Подушка 207 45 х 65 см

К счастью, SKU в этих редких случаях — это первое целое число, встречающееся в названии.

Итак, что мне нужно, так это preg_replace исправить приведенные выше полностью испорченные заголовки, чтобы мой шаблон мог правильно извлечь SKU.

Заранее большое спасибо.

Существует ли минимальное количество цифр в каждом SKU? Похоже на 3, но требует уточнения

Phil 07.02.2023 01:54

3-значный номер — это минимальный SKU, который я могу наблюдать. Затем, как я уже сказал, есть E9999 (3 или 4 числа), 9999 A (3 или 4 числа) и 9999A (3 или 4 числа).

Faye D. 07.02.2023 01:57

@sln OP говорит, что SKU - это первое целое число

Phil 07.02.2023 02:11

@sln, если бы моя работа была на кону, я бы нашел способ получше, чем разбор заголовков 😉

Phil 07.02.2023 05:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используйте границы слов (\b), чтобы отделить SKU от любых других символов, а затем просто проверьте наличие определяющих символов.

Границы гарантируют, что вы не сопоставите 258 G и 258 Game of Thrones ложно.

$rx = '/\bE?\d{3,}( ?[A-Z])?\b/';
if (preg_match($rx, $title, $matches)) {
    [ $sku ] = $matches;
}

https://3v4l.org/rCEqD

Это блестящий Фил, и это именно то, что мне нужно! Остается только одно, это какой-нибудь preg_replace для исправления заголовка, то есть привести распознанный SKU в начало, а потом и весь заголовок (предварительно вынув часть SKU, которая была перемещена).

Faye D. 07.02.2023 02:19

@ФайД. проверьте этот ответ

Phil 07.02.2023 02:23

Фил, я только что заметил это: часть шаблона \d{3,} хорошо работает для приведенных примеров, но если размерная часть заголовка представляет собой трехзначное число, например 150 x 150 см, это идентифицирует его как часть SKU. Возьмем, к примеру, это: regex101.com/r/fF4GYy/1, где он неправильно идентифицирует SKU для 5-го названия. В идеале он не должен использовать шаблон минимальной цифры. Он должен обнаружить первое целое число, поэтому в качестве SKU должен быть возвращен код 245 150 x 150 см.

Faye D. 07.02.2023 02:33

@ФайД. вы сказали, что SKU был первым целым числом, поэтому не должно иметь значения, если за ним следуют какие-либо другие числа. Используйте параметр $limit для preg_replace(), если вы получаете несколько совпадений

Phil 07.02.2023 02:37

Но это имеет значение в вашем решении, к сожалению. Попробуйте этот заголовок, например: Decorative pillow / Set with bed covers 256 155Χ55cm

Faye D. 07.02.2023 02:41

@ФайД. этот точный пример находится в ссылке 3v4l.org, которую я предоставил

Phil 07.02.2023 02:44

Виноват! Действительно, в вашем коде он отлично работает! Однако здесь regex101.com/r/mmpelA/1 похоже работает неправильно! Не могли бы вы понять, почему? Что я пропустил для переноса?

Faye D. 07.02.2023 02:46

Там вы найдете все совпадения. preg_match() найти только первый. Если вы используете preg_replace(), используйте параметр $limit, чтобы избежать множественных замен.

Phil 07.02.2023 02:50

Я могу ответить на часть шаблона RegEx: (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

Другие вопросы по теме