Python программный синтаксический анализ сложной строки - PullRequest
0 голосов
/ 07 августа 2020

Не уверен, что это можно сделать программно. Я пробовал различные примеры, найденные на SO, но эксперт может взглянуть и быстро сказать: «Хватит тратить свое время».

Пример 2 <- ПОСМОТРИТЕ НА ЭТО </strong>

  • Использование Python
  • df, содержащего: 21000 строк × 26 столбцов
  • 1 столбец содержит «краткое описание», как показано в двух примерах ниже, но существует множество различных наборов данных.
  • В идеале элементы, выделенные синим цветом (связанные изображения), должны были бы стать именами столбцов, а данные белого цвета - в строке. Если какой-либо из 2100 элементов имеет значение для именованного столбца, он будет заполнен правильно.
  • Однако, если я могу выбрать только один элемент df и разобрать его на два столбца (содержимое левого столбца - синий, правый столбец - белый содержимое), что было бы приемлемо.

Анализ:

"Подключение = Кабель с разъемом, M12x1-Male, 4-контактный, 0,30 м , Версия = Фоновая подсветка, Размер = 43 x 9,5 x 64,5 мм, Номинальное рабочее напряжение Ue DC = 24 В, Максимальный потребляемый ток = 208 мА, Рабочий режим = Нормальный, Материал = анодированный алюминий, черное стекло PMMA, Площадь освещения = 25 x 25 мм, тип света = светодиодный красный свет, длина волны = 617 нм, освещенность (0,1 м) = 350 люкс, угол луча = 40 ° x 40 °, температура окружающей среды = -10 ... 55 ° C, допуск / Соответствие = CE; EAC; WEEE, рейтинг IP = IP54 "

или

Группа продуктов = HF (13,56 МГц), Название продукта = WLAN, Размер = 100 x 51 x 265 мм, Тип антенны = Стержень, Поддерживаемые типы носителей данных = DIN ISO 14443; DIN ISO 15693, Дисплей = сенсорный TFT-дисплей (цветной), разрешение 480x640 VGA, клавиатура = 52 клавиши, буквенно-цифровые c, рабочее напряжение Ub = 3,7 В C Аккумулятор, температура хранения = -40 ... 60 ° C, температура окружающей среды = -10 ... 50 ° C, степень защиты IP = IP65, аттестация / соответствие = CE; WEEE

или ...

Пример 1

Файл Excel с дополнительными "краткими описаниями" "

1 Ответ

0 голосов
/ 07 августа 2020

Несколько хакерское решение: манипуляция строкой по следу и ошибке

Наблюдение: пары описание-значение разделены , .

Итак, давайте попробуем разделить строку по этим разделителям:

line = "Connection=Cable with connector, M12x1-Male, 4-pin, 0.30
 m, Version=Background light, Dimension=43 x 9.5 x 64.5 mm, Rated operating volt
age Ue DC=24 V, Current draw max.=208 mA, Operating mode=Normal, Material=Alumin
um anodized, black Glass PMMA, Illumination area=25 x 25 mm, Light type=LED Red 
light, Wave length=617 nm, Illuminence (0.1 m)=350 Lux, Beam angle=40 ° x 40 °, 
Ambient temperature=-10...55 °C, Approval/Conformity=CE; EAC; WEEE, IP rating=IP
54"

line.split(', ')

Были ли запятые (,) без пробела? Давайте проверим, есть ли в результате разделения запятые:

>>> any(',' in part for part in line.split(', '))
False

Хорошо.

Наблюдение: описание и значение разделены =.

Давайте проверим, все ли части, которые мы идентифицировали, содержат =:

>>> all('=' in x for x in line.split(', '))
False

Ха. Что произошло? Давайте посмотрим на полный результат:

>>> line.split(', ')
['Connection=Cable with connector',
 'M12x1-Male',
 '4-pin',
 '0.30 m',
 'Version=Background light',
 'Dimension=43 x 9.5 x 64.5 mm',
 'Rated operating voltage Ue DC=24 V',
 'Current draw max.=208 mA',
 'Operating mode=Normal',
 'Material=Aluminum anodized',
 'black Glass PMMA',
 'Illumination area=25 x 25 mm',
 'Light type=LED Red light',
 'Wave length=617 nm',
 'Illuminence (0.1 m)=350 Lux',
 'Beam angle=40 ° x 40 °',
 'Ambient temperature=-10...55 °C',
 'Approval/Conformity=CE; EAC; WEEE',
 'IP rating=IP54']

Ага: Похоже, есть значения, которые содержат , :

  • Cable with connector, M12x1-Male, 4-pin, 0.30 m
  • Aluminum anodized, black Glass PMMA

, и они тоже были разделены.

Давайте просто объединим эти:

fake_parts = line.split(', ')
real_parts = []

for part in fake_parts:
    if '=' in part:
        real_parts.append(part)
    else:
        real_parts[-1] += f', {part}'

Как это выглядит?

>>> real_parts
['Connection=Cable with connector, M12x1-Male, 4-pin, 0.30 m',
 'Version=Background light',
 'Dimension=43 x 9.5 x 64.5 mm',
 'Rated operating voltage Ue DC=24 V',
 'Current draw max.=208 mA',
 'Operating mode=Normal',
 'Material=Aluminum anodized, black Glass PMMA',
 'Illumination area=25 x 25 mm',
 'Light type=LED Red light',
 'Wave length=617 nm',
 'Illuminence (0.1 m)=350 Lux',
 'Beam angle=40 ° x 40 °',
 'Ambient temperature=-10...55 °C',
 'Approval/Conformity=CE; EAC; WEEE',
 'IP rating=IP54']

>>> all('=' in part for part in real_parts)
True

Многое лучше!

Все ли части теперь содержат ровно один =? Попробуем разделить их:

>>> all(len(part.split('=')) == 2 for part in real_parts)
True

Хорошо. При этом мы можем сформировать словарь:

>>> from collections import OrderedDict

>>> OrderedDict(part.split('=') for part in real_parts)
OrderedDict([('Connection', 'Cable with connector, M12x1-Male, 4-pin, 0.30 m'),
             ('Version', 'Background light'),
             ('Dimension', '43 x 9.5 x 64.5 mm'),
             ('Rated operating voltage Ue DC', '24 V'),
             ('Current draw max.', '208 mA'),
             ('Operating mode', 'Normal'),
             ('Material', 'Aluminum anodized, black Glass PMMA'),
             ('Illumination area', '25 x 25 mm'),
             ('Light type', 'LED Red light'),
             ('Wave length', '617 nm'),
             ('Illuminence (0.1 m)', '350 Lux'),
             ('Beam angle', '40 ° x 40 °'),
             ('Ambient temperature', '-10...55 °C'),
             ('Approval/Conformity', 'CE; EAC; WEEE'),
             ('IP rating', 'IP54')])

или просто

>>> dict(part.split('=') for part in real_parts)
{'Ambient temperature': '-10...55 °C',
 'Approval/Conformity': 'CE; EAC; WEEE',
 'Beam angle': '40 ° x 40 °',
 'Connection': 'Cable with connector, M12x1-Male, 4-pin, 0.30 m',
 'Current draw max.': '208 mA',
 'Dimension': '43 x 9.5 x 64.5 mm',
 'IP rating': 'IP54',
 'Illumination area': '25 x 25 mm',
 'Illuminence (0.1 m)': '350 Lux',
 'Light type': 'LED Red light',
 'Material': 'Aluminum anodized, black Glass PMMA',
 'Operating mode': 'Normal',
 'Rated operating voltage Ue DC': '24 V',
 'Version': 'Background light',
 'Wave length': '617 nm'}

Теперь это то, с чем вы, вероятно, можете работать. Однако этот подход выглядит так: fr agile:

  • Что, если некоторые описания также содержат , ?
  • Что, если описания или значения содержат =?
  • Что, если формат содержит определенные c escape-последовательности?

Правильное решение: используйте синтаксический анализатор

Чтобы правильно интерпретировать данные, закодированные как текст, в соответствии со сложной (или нет так продумайте) набор правил, используйте библиотеку парсера. См., Например, Как лучше всего разобрать простую грамматику? для параметров.

Однако для этого необходимо указать точный набор правил (называемых «грамматикой»), которые управляют кодировкой, и, таким образом, также знайте эти правила. Могут ли и насколько хорошо эти правила могут быть выведены на основе просмотра закодированных данных, зависит от этих данных.

...