openrefine извлекает число из текстового столбца с помощью регулярных выражений
Я пытаюсь проанализировать столбец данных из набора данных OpenFoodFacts, который я нашел через Kaggle. Существует атрибут с названием "serve_size", который содержит любую информацию о размере порции, представленную на упаковке для продукта питания. Большую часть времени размер порции выражается в граммах (г), однако часто есть и другой текст. Я хотел бы иметь возможность искать в строке, найти число, соответствующее количеству граммов, и извлечь это значение в собственное поле. Значение не просто целое число - оно может иметь десятичное число.
Я новичок в регулярных выражениях, но похоже, что должен быть возможен поиск символа "g" и если после него используются какие-либо числовые значения для их извлечения. Я нашел несколько рецептов, которые предполагают, что это возможно, но пока ничего из того, что я пробовал, не сработало. В документации OpenRefine они приводят пример извлечения десятичных данных с использованием этого регулярного выражения: /[-+]?[0-9]+(.[0-9]+)?/, но не было никакого варианта, который я мог бы получить работать в нашем сценарии. Я также пробовал команды типа "value.match (/ (.)? (/ D + [g]).? /)". Я обнаружил, что не понимаю, как регулярное выражение должно работать - когда я говорю это "/d", я ожидаю, что он вернет мне ТОЛЬКО числовые значения, однако это не так - это дает все, что есть, независимо от типа персонажа.
Любая помощь будет оценена.
Вот несколько примеров текстовых строк из данных:
serving_size
- 113.5g
- 20g
- 1 cup (227g)
- 4 cookies (15g)
- 13 pieces (39g)
- 1/4 packet (21g) makes 1/2 cup
- 0.75 oz (21g)
- 1 can (12 FL OZ) 355g
- 15.2 fl oz (450g)
- 1 can (355mL)
- 1/4 tsp (1.4g)
- 10 fl oz 1 bottle.
- 20 fl oz
- 1 envelope (21g)
- 1 tbsp (4.5g)
- 45.2g
- 1/2 pack 142.5gms
- 1 carré de chocolat de 20g
- 4 biscottes (≈ 35g) Ce paquet contient 8.5 portions de 4
biscottes.
- 0.33L
- 2galettes 10.5g
- 0.041649313g
- 1 package (79g)
1 ответ
В OpenRefine GREL (языке, используемом для написания преобразований) функция 'match' требует, чтобы регулярное выражение совпадало со всей строкой в ячейке - вы не можете использовать частичное совпадение.
Выходные данные функции match - это массив всех групп захвата. Чтобы получить конкретное значение, вы должны выбрать его из массива или преобразовать массив в строку.
Так, например, вы можете попробовать:
value.match(/.*?(\d+\.?\d*)g(ram)?(s)?\b?.*/)[0]
При этом будут найдены все строки, в которых есть число (с десятичной точкой или без нее) перед буквой "g", или "грамм", или "грамм", за которым следует несловесный символ (например, пробел или скобка).) и будет захватывать число в качестве первого члена результирующего массива групп захвата.
'?' нужен после первого '. *', чтобы сделать это ленивым, чтобы группа захвата получила все число, а не только последнюю цифру.