2016-10-20 3 views
0

Я пытаюсь заменить появление слова, которое происходит только после другого слова в текстовой строке JSON. Я пытаюсь использовать регулярные выражения для этого, но использование только функций Python будет в порядке со мной.В Python, соответствующем первому вхождению слова ПОСЛЕ появления другого слова

Так что я хочу, чтобы найти первое вхождение "LEVEL1": (с кавычками), а затем найти первое вхождение "session_transition":, а затем найти то, что строка в кавычках после "session_transition":, а затем заменить его на другую строку. Вот строка я работаю с:

"BASELINE": { 
    "audio_volume": 150, 
    "cry_threshold": 70, 
    "cry_transition": "LEVEL1", 
    "expected_volume": 63, 
    "led_color": "BLUE", 
    "led_blink_speed": "NONE", 
    "motor_amplitude": 0.97, 
    "motor_frequency": 0.5, 
    "power_transition": "SUSPENDED", 
    "seconds_to_ignore_cry": 10.0, 
    "seconds_in_state": -1.0, 
    "session_transition": "ONLINE", 
    "track": "RoR", 
    "timer_transition": null, 
    "active_session" : 1 
}, 
"LEVEL1": { 
    "audio_volume": 300, 
    "cry_threshold": 75, 
    "expected_volume": 63, 
    "cry_transition": "LEVEL2", 
    "led_color": "PURPLE", 
    "led_blink_speed": "NONE", 
    "motor_amplitude": 0.76, 
    "motor_frequency": 1.20, 
    "power_transition": "SUSPENDED", 
    "seconds_to_ignore_cry": 10.0, 
    "seconds_in_state": 480.0, 
    "session_transition": "ONLINE", 
    "track": "RoR", 
    "timer_transition": "BASELINE", 
    "active_session" : 1 
} 

}

Например, ниже я хочу найти и заменить "ONLINE" под "LEVEL1": ->"session_transition": в "OFFLINE" так он будет выглядеть следующим образом:

"LEVEL1": { 
    "audio_volume": 300, 
    "cry_threshold": 75, 
    "expected_volume": 63, 
    "cry_transition": "LEVEL2", 
    "led_color": "PURPLE", 
    "led_blink_speed": "NONE", 
    "motor_amplitude": 0.76, 
    "motor_frequency": 1.20, 
    "power_transition": "SUSPENDED", 
    "seconds_to_ignore_cry": 10.0, 
    "seconds_in_state": 480.0, 
    "session_transition": "OFFLINE", 
    "track": "RoR", 
    "timer_transition": "BASELINE", 
    "active_session" : 1 
} 

До сих пор у меня есть r"(?<=\"LEVEL1\"\:).*, чтобы соответствовать первому вступлению, но не знаю, как продолжить дальше.

+0

Почему вы пытаетесь сделать это с помощью регулярного выражения? Разберите его и обработайте словарь. – jonrsharpe

+0

@jonrsharpe: Мне нужна строка, чтобы оставаться строкой, а не стать dict, если это то, что вы имеете в виду. – RebelAlliance

+0

Почему? Почему вы не можете вернуть его обратно в строку? Какую * актуальную проблему вы пытаетесь решить? – jonrsharpe

ответ

0

Хорошо, так что я был в состоянии решить эту проблему следующим образом:

#1)Find the unique string "LEVEL1": and save its index 
after_index = configuration_in_text_format.index('"LEVEL1":') 
#2)Starting from previous index, find the "session_transition": string and save its index 
after_index = configuration_in_text_format.find('"session_transition":', after_index) 
#3)Create a new string of bottom part with "session_transition": as first line 
new_config_in_text_format = configuration_in_text_format[after_index:] 
#4)Remove the first line with "session_transition": in it 
new_config_in_text_format = new_config_in_text_format[new_config_in_text_format.find('\n')+1:] 
#5)Create a new string to replace the deleted new line 
new_line_str = '"session_transition": "OFFLINE",\n' 
#6)Put new string on top of remaining text, effectively replacing old line 
new_config_in_text_format = new_line_str + new_config_in_text_format 
#7)Take the top part of original text and append the newly modified bottom part 
new_config_in_text_format = configuration_in_text_format[:after_index] + new_config_in_text_format 
print new_config_in_text_format 

И надлежащий выход:

"BASELINE": { 
    "audio_volume": 150, 
    "cry_threshold": 70, 
    "cry_transition": "LEVEL1", 
    "expected_volume": 63, 
    "led_color": "BLUE", 
    "led_blink_speed": "NONE", 
    "motor_amplitude": 0.97, 
    "motor_frequency": 0.5, 
    "power_transition": "SUSPENDED", 
    "seconds_to_ignore_cry": 10.0, 
    "seconds_in_state": -1.0, 
    "session_transition": "ONLINE", 
    "track": "RoR", 
    "timer_transition": null, 
    "active_session" : 1 
}, 
"LEVEL1": { 
    "audio_volume": 300, 
    "cry_threshold": 75, 
    "expected_volume": 63, 
    "cry_transition": "LEVEL2", 
    "led_color": "PURPLE", 
    "led_blink_speed": "NONE", 
    "motor_amplitude": 0.76, 
    "motor_frequency": 1.20, 
    "power_transition": "SUSPENDED", 
    "seconds_to_ignore_cry": 10.0, 
    "seconds_in_state": 480.0, 
    "session_transition": "OFFLINE", 
    "track": "RoR", 
    "timer_transition": "BASELINE", 
    "active_session" : 1 
}, 
0

Я думаю, что вы можете сделать это несколько легко с помощью string.index()

first_index = some_string.index('"Level1"') 
second_index = some_string[first_index:].index('"Online"') 

после того, что я оставляю это до вас, чтобы заменить строку. Вы должны сделать это, используя some_string[second_index:].split('"'), а затем используйте сплайсинг и присоедините его, чтобы вернуть его обратно.

+0

«ОНЛАЙН», который я хочу заменить, не является первым, с которым я сталкиваюсь; на самом деле это может быть любая другая строка, если она находится в ветке LEVEL1 -> session_transition. Вот почему я пытаюсь совместить с «LEVEL1»: сначала, а затем матч с «session_transition»: next (в этом порядке). – RebelAlliance

+0

ОК, так что переключите слова вокруг? точка - это первая строка, которую вы сопоставляете с словом, которое вы хотите совместить в первую очередь, а вторая строка совпадает с словом, которое вы хотите совместить со вторым. – bravosierra99

+0

Спасибо, это привело меня к решению. Я по ошибке спустился по бездонной бездне регулярного выражения; урок выучен. – RebelAlliance

0

Я предлагаю вам использовать библиотеку JSON, которая встроена в Python. Вы можете легко преобразовать JSON в объект Python Dict. Это также помешает вам создать сложное регулярное выражение. Лучше также уменьшить сложность в удобочитаемости. Документация: Python 3.4 Python 2.7

В Python 2

import json 
jsonDict = json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') 
print(jsonDict) 

Результат:

['foo', {'bar': ['baz', None, 1.0, 2]}] 

Вы можете легко сделать манипуляции, как вы могли бы сделать в Python словарь. Кажется более интуитивным этот путь.

После того, как вы закончите вы можете преобразовать его с помощью

jsonStr = json.dumps(jsonDict) 
print(jsonStr) 

Результат:

["foo", {"bar":["baz", null, 1.0, 2]}] 
+0

Это хорошее решение, и оно работает. Однако, когда я конвертирую обратно в строку из JSON, данные переупорядочиваются. Я знаю, что это ожидается, но я не хочу, чтобы строка была изменена, чтобы быть не в порядке от ее начального состояния. – RebelAlliance

Смежные вопросы