Шаблон является регулярным, за исключением того, что свойства расположены в любом порядке, так что это, безусловно, выполнимо.Я сделал это в два шага - один regex, чтобы получить цвет в начале и извлечь строку свойств, и второй, чтобы извлечь свойства.
import re
inputs = [
'(Names RED (property (x 123) (y 456) (type MT) (label ONE) (code XYZ)))',
'(Names GREEN (property (type MX) (label TWO) (x 789) (y 101)))'
]
# Get the initial part, and chop off the property innerstring
initial_re = re.compile('^\(Names\s([^\s]*)\s\(property\s(.*)\)\)')
# Get all groups from (x 123) (y 456) (type MT) (label ONE) (code XYZ)
prop_re = re.compile('\(([^\s]*)\s([^\s]*)\)')
for s in inputs:
parts = initial_re.match(s)
color = parts.group(1)
props = parts.group(2)
# e.g. (x 123) (y 456) (type MT) (label ONE) (code XYZ)
properties = prop_re.findall(props)
# [('x', '123'), ('y', '456'), ('type', 'MT'), ('label', 'ONE'), ('code', 'XYZ')]
print("%s: %s" % (color, properties))
Выходные данные:
RED: [('x', '123'), ('y', '456'), ('type', 'MT'), ('label', 'ONE'), ('code', 'XYZ')]
GREEN: [('type', 'MX'), ('label', 'TWO'), ('x', '789'), ('y', '101')]
Чтобы получить это в pandas
, вы можете накапливать свойства в словаре списков (я сделал это ниже, используя defaultdict
).Вам нужно что-то хранить для пустых значений, чтобы все столбцы имели одинаковую длину, здесь я просто храню None (или null).Наконец, используйте pd.DataFrame.from_dict
, чтобы получить окончательный результат DataFrame
.
import re
import pandas as pd
from collections import defaultdict
inputs = [
'(Names RED (property (x 123) (y 456) (type MT) (label ONE) (code XYZ)))',
'(Names GREEN (property (type MX) (label TWO) (x 789) (y 101)))'
]
# Get the initial part, and chop off the property innerstring
initial_re = re.compile('^\(Names\s([^\s]*)\s\(property\s(.*)\)\)')
# Get all groups from (x 123) (y 456) (type MT) (label ONE) (code XYZ)
prop_re = re.compile('\(([^\s]*)\s([^\s]*)\)')
columns = ['color', 'x', 'y', 'type', 'label', 'code']
data_dict = defaultdict(list)
for s in inputs:
parts = initial_re.match(s)
color = parts.group(1)
props = parts.group(2)
# e.g. (x 123) (y 456) (type MT) (label ONE) (code XYZ)
properties = dict(prop_re.findall(props))
properties['color'] = color
for k in columns:
v = properties.get(k) # None if missing
data_dict[k].append(v)
pd.DataFrame.from_dict(data_dict)
Окончательный результат -
color x y type label code
0 RED 123 456 MT ONE XYZ
1 GREEN 789 101 MX TWO None