Найдите правильное регулярное выражение

У меня есть такие категории: Основные категории (кошка):

  • 1
  • 2
  • ..
  • 15

Пример подкаталога:

Для основной категории 1:

  • 1.1.2
  • 1.1.3
  • 1,2
  • 1.11.2

Для основной категории 2:

  • 2.1.2
  • 2.1.2.4
  • 2.12.4

Для основной категории 15:

  • 15.11.12

Я хотел бы найти регулярное выражение для MYSQL, которое находит категории, начинающиеся с категории.

Например (с примером выше):


Поиск категорий начинается с 1 должен вернуться:

  • 1.1.2
  • 1.1.3
  • 1,2
  • 1.11.2
  • Если я сделаю свое регулярное выражение, у меня будет это:

  • 1.1.2
  • 1.1.3
  • 1,2
  • 1.11.2
  • 15.11.12
  • (I don't want that)

    Поиск категорий начинается с 1.1 должен вернуться:

  • 1.1.2
  • 1.1.3
  • Если я сделаю свое регулярное выражение, у меня будет это:

  • 1.1.2
  • 1.1.3
  • 1.11.2
  • (I don't want that)

    Поиск категорий начинается с 2.1 должен вернуться:

  • 2.1.2
  • 2.1.2.4
  • Если я сделаю свое регулярное выражение, у меня будет это:

  • 2.1.2
  • 2.1.2.4
  • 2.12.4
  • (I don't want that)

    Спасибо за помощь :)

    Похоже, вам нужно использовать \b

    Andreas 30.01.2019 13:03

    Мне интересно, что именно вы используете для своего RegEXP - php или sql. У них разный синтаксис. Мне также интересно, к какому синтаксису относится \b. Я не могу найти ссылку на синтаксис SQL(actually MySQL) за 5 минут, но я знаю, что это совершенно правильный Php synthax

    Eugene Anisiutkin 30.01.2019 13:15

    Спасибо, я использую mysql для регулярного выражения. Я проверю \b. Я нашел это для \b: [stackoverflow.com/questions/6403104/…]), но я не знаю, как должно выглядеть мое регулярное выражение

    webmaster Chp 30.01.2019 13:39

    что ты уже испробовал?

    Nico Haase 30.01.2019 14:07
    Стоит ли изучать PHP в 2026-2027 годах?
    Стоит ли изучать PHP в 2026-2027 годах?
    Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
    67
    3
    Перейти к ответу Данный вопрос помечен как решенный

    Ответы 3

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

    Я не думаю, что вам вообще нужно регулярное выражение, и, возможно, оно слишком усложняет его.

    Если вы знаете, какую категорию вы хотите найти, предполагая, что пользователь запрашивает раздел «1.1», раздел «1.2» или «1.4.1», вы можете искать с помощью подстановочного знака.

    Вы не упоминаете, хранятся ли эти данные в виде десятичного числа или varchar, поэтому я предполагаю, что это varchar, и только потому, что в большинстве баз данных, которые я когда-либо видел, они всегда сохраняются именно так.

    Итак, если категория была 1.1, а вы хотели 1.1.0, 1.1.1, 1.1.12 и т. д., вы просто искали бы все, что соответствует 1.1.%, что означает поиск всего, что соответствует 1.1, за которым следует точка, а не следует непосредственно число.

    Пример запроса:

    $category = "1.1";
    $sql = "SELECT * FROM [your_table] WHERE cat LIKE '".$category.".%'";
    

    Этот запрос будет соответствовать:

    1.1.0
    1.1.1
    1.1.15
    // Any anything else starting with 1.1.
    

    Спасибо, я чувствую себя глупо, что не подумал об этом простом запросе... это быстрее, чем Regex?

    webmaster Chp 30.01.2019 14:16

    @AdamWhateverson - «Поиск категорий, начинающихся с 1.1, должен вернуться» не включает «1.1». Пожалуйста, добавьте его или уточните, что он намеренно исключен. Другие ответы либо медленные, либо неправильные.

    Rick James 01.02.2019 16:58

    Для MySQL до 8.0.4 вы можете использовать маркер конца слова ([[:>:]]) в регулярном выражении, чтобы избежать выбора подкатегорий, начинающихся, например, с. 2.12, когда вы ищете 2.1. Попробуйте что-то вроде этого:

    SELECT *
    FROM yourtable
    WHERE category RLIKE '^2.1[[:>:]]'
    

    Для MySQL 8.0.4 и более поздних версий он поддерживает \b в качестве границы слова, и вы можете использовать его вместо этого (обратите внимание на необходимость дублировать \, поскольку MySQL интерпретирует его как escape-символ внутри строк):

    SELECT *
    FROM yourtable
    WHERE category RLIKE '^2.1\\b'
    

    Для основной категории 1: LIKE '1.%'
    Для основной категории 15: LIKE '15.%'
    . Для категории 2.1: LIKE '2.1.%'

    Кроме того, используя LIKE, вы можете использовать INDEX(cat) для повышения производительности.

    Но... Этого может быть недостаточно. (И я утверждаю, что Вопрос был здесь неоднозначным.) Если может быть запись только с '2.1' (без подкаталога), то эти лайки неадекватны. Так...

    План A: col REGEXP '^2[.]1([.]|$)' -- Но REGEXP не будет использовать никаких индексов.

    План Б: col = '2.1' OR col LIKE '2.1.%' -- ButOR` предотвращает использование index.

    План C: неуклюжий, но самый быстрый для больших наборов данных (из-за индекса):

        WHERE col LIKE '2.1%'             -- uses INDEX(col) for quick filtering
          AND col REGEXP '^2[.]1([.]|$)'  -- avoids "2.15" and other things
    

    Почему скобки вокруг .?:

    • . сам по себе соответствует любому одному символу - не нужно этого
    • [.] соответствует любому набору символов, включая только точку
    • \. соответствует точке, но, в зависимости от контекста, вам может понадобиться 1, 2 или 4 обратной косой черты.

    Итог: для простоты используйте план B. Для производительности используйте план C.

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