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", или "грамм", или "грамм", за которым следует несловесный символ (например, пробел или скобка).) и будет захватывать число в качестве первого члена результирующего массива групп захвата.

'?' нужен после первого '. *', чтобы сделать это ленивым, чтобы группа захвата получила все число, а не только последнюю цифру.

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