Możesz użyć wyrażenia regularnego, przechwytując wszystkie "ustalone" grupy i używając tego, co zostało na info
. Powinno to nawet zadziałać, jeśli część info
zawiera znaki ,
lub =
. Oto krótki przykład (używając Pythona, ale to nie powinno być problemem ...).
>>> p = r"(type=[A-Z]+), (languageCode=[-A-Z]+), (url=[^,]+), (ref=\d), (info=.+?), (deactivated=(?:true|false))"
>>> s = "type=INFO, languageCode=EN-GB, url=http://www.stackoverflow.com, ref=1, info=Text, that may contain all kind of chars, even deactivated=true., deactivated=false"
>>> re.search(p, s).groups()
('type=INFO',
'languageCode=EN-GB',
'url=http://www.stackoverflow.com',
'ref=1',
'info=Text, that may contain all kind of chars, even deactivated=true.',
'deactivated=false')
Jeśli którykolwiek z tych elementów są opcjonalne, można umieścić ?
po tych grup, i sprawiają, że przecinek opcjonalne. Jeśli zamówienie może być inne, to jest bardziej skomplikowane. W tym przypadku, zamiast używać jednego RegEx do przechwytywania wszystkiego na raz, użyj kilku RegExes, aby przechwycić poszczególne atrybuty, a następnie usuń (zamień na ''
) elementy w łańcuchu przed dopasowaniem następnego atrybutu. Wreszcie, dopasuj info
.
Na dalszych rozważań, biorąc pod uwagę, że te cechy mogą mieć dowolną kolejność, może być bardziej obiecujące, aby uchwycić tylko wszystko rozciąga się od jednego słowa kluczowego do następnego, niezależnie od jego rzeczywistej zawartości, bardzo podobny do rozwiązania Pshemo za:
keys = "type|languageCode|url|ref|info|deactivated"
p = r"({0})=(.+?)(?=\, (?:{0})=|$)".format(keys)
matches = re.findall(p, s)
Ale to też może się nie udać w niektórych bardzo niejasnych przypadkach, np. jeśli atrybut info
zawiera coś w rodzaju ', ref=foo'
, w tym przecinek. Jednak wydaje się, że nie ma możliwości obejścia tych dwuznaczności. Jeśli masz ciąg znaków, taki jak info=in this string, ref=1, and in another, ref=2, ref=1
, czy zawiera on jeden atrybut ref
lub trzy, czy nie ma go wcale?
Czy kolejność tych elementów stałe? – Pshemo
Co powiesz na wyszukanie '=', a następnie wybierz jedno słowo przed nim jako nazwę pola. Wszystko po '=' do następnego pola jest wartością. Zakłada się, że wartość nie może zawierać "=" - jeśli to możliwe, nie masz zbyt wiele do zrobienia. – xxbbcc
Jeśli wszystkie atrybuty _other_ mają nieco przewidywalny format, możesz je usunąć i zabrać wszystko, co zostało dla 'info' ... –