Мне нужно извлечь объем с помощью регулярного выражения из строк типа «Кэнди БАР 350Г» (объем = 350Г),
«Джин Барристер 0,9мл» (объем=0,9мл),
«Джин BAXTER DRY 40% 0,5 мл» (объем = 0,5 мл),
"СЛАДКАЯ КУКУРУЗА 340Г/425МЛ ГЛОБУС" (объем = 340Г/425МЛ)
Я попробовал использовать '\d+\S*[gGMmLl]'
и это сработало хорошо, но я столкнулся со строками типа «Candies 2x150G» (объем, который мне нужен, 150G, но я получаю 2x150G) или
«ПИЩЕВЫЕ КРАСИТЕЛИ 3COL.9G» (мне нужно 9G, но я получаю 3COL.9G)
Я не знаю, что еще добавить к регулярному выражению
Начнем с полного кода, и мы можем разбить его на более мелкие блоки:
import re
fluids = [
"Candy BAR 350G",
"Gin Barrister 0.9ml",
"BAXTER DRY Gin 40% 0.5 ml",
"SWEET CORN 340G/425ML GLOBUS",
"Candies 2x150G",
"FOOD DYES 3COL.9G"
]
pattern = r"(\d[\d.]{0,})\s?(ml|g)"
for fluid in fluids:
print(re.findall(pattern, fluid, flags=re.IGNORECASE))
который производит
[('350', 'G')]
[('0.9', 'ml')]
[('0.5', 'ml')]
[('340', 'G'), ('425', 'ML')]
[('150', 'G')]
[('9', 'G')]
Во-первых, обратите внимание, что мы упрощаем нашу жизнь, передавая флаг регулярного выражения re.IGNORECASE
. Мы также проверяем, что шаблон представляет собой необработанную строку, используя r"..."
, чтобы Python не смеялся над обратными косыми чертами в шаблоне (в противном случае он думает, что пользователь пытается экранировать символы в строке, хотя это не входит в наши намерения).
Если шаблону регулярного выражения Python передается что-либо внутри скобок (...)
без каких-либо утверждений, таких как ?=
или ?!
, оно становится группой захвата. В зависимости от уровня вложенности вы сообщаете методу регулярного выражения, какую именно часть шаблона вы хотите вернуть пользователю. Мы используем группы захвата, чтобы не фиксировать текст с пробелами (который мы ищем с помощью \s?
), а вместо этого фиксируем количество (\d[\d.]{0,})
и единицы измерения (ml|g)
. Поскольку группы захвата для тома и единиц измерения находятся на одном уровне вложенности, они возвращаются в виде кортежа при обнаружении re.findall
.
Числа были записаны с использованием шаблона регулярного выражения \d[\d.]{0,}
, который говорит: ищите что-то, что должно начинаться с цифры (\d
), а затем следовать любой комбинации символов ([\d.]
) (представляющих любую цифру или точку) от нуля до любого количество повторений ({0,}
).
Единицы захватываются с помощью ml|g
, указывая интерпретатору либо соответствовать ml
, либо g
во второй группе захвата.
Надеюсь это поможет.
Вы хотите
'\s'
, а не'\S'