Регулярные выражения содержащие ()

135
07 октября 2019, 00:20

Возник вопрос. Необходимо разобрать строку. В строке содержатся ключевые слова, которые я знаю заранее и мне надо вытащить всё, что между данными словами находится.

Например:

Категория Косметика Подкатегория Масла Объем (мл) 25 

Из этой строки необходимо составить набор записей (для этого использую HashMap<String, String>) и получить необходимо набор записей по типу (key, value) (Категория, Косметика), (Подкатегория, Масла), (Объем (мл), 25).

Так как получаю строку с известными key, то остается выбрать лишь value.

pattern = Pattern.compile(".*?" + info.get(k) + " (.*?) " + info.get(k+1));

В info хранятся ключи. Столкнулся с проблемой нахождения записи подкатегории и объема в строке. Возникает скорее всего из-за (мл) у объема, но как это решить не совсем понятно.

Answer 1

Тут необходимо использовать Pattern.quote для экранирования любых специальных символов регулярок, а также добавить |\s*\z к info.get(k+1), чтобы найти совпадение также в конце строки.

Pattern pattern = Pattern.compile(Pattern.quote(info.get(k)) + "\\s+(.*?)(?:\\s+" + Pattern.quote(info.get(k+1)) + "|\\s*\\z)");

Например, при последней итерации регулярка будет выглядеть примерно так:

\QОбъем (мл)\E\s+(.*?)(?:\s+|\s*\z)

См. демо

Подробности

  • \Q - далее все символы перестают быть специальными ("режим буквального текста")
  • Объем (мл) - фраза (подстрока) Объем (мл)
  • \E - конец режима буквального текста
  • \s+ - 1+ пробельных символов
  • (.*?) - Захватывающая подмаска №1: 0 и более символов, отличных от символов перевода строки, как можно меньше
  • (?: - начало подмаски:
    • \s+ - 1+ пробельных символов
    • | - или
    • \s*\z - 0+ пробельных символов и самый конец строки
  • ) - конец подмаски.
READ ALSO
Vkontakte API ошибка: error: invalid_client, error_description; client_id is incorrect

Vkontakte API ошибка: error: invalid_client, error_description; client_id is incorrect

Делаю авторизацию в вк по этому видео

147
Как сделать квадратное поле в консоли?

Как сделать квадратное поле в консоли?

Мне нужно, чтобы в консоли вывелось квадратное поле из #, например, размером 5x5 Но у меня это не совсем выходит:

127
Преобразовать Object в ArrayList

Преобразовать Object в ArrayList

Доброго времени! Собственно ошибка в этой части profiles = deserData("profiles")); Сразу после main

186
Как в цикле пройти по однотипным элементам?

Как в цикле пройти по однотипным элементам?

У меня элементов текстовое поле довольно много, к ним нужно применить одинаковые действия при нажатии на кнопку, называются они однотипно:...

86