2015-05-12 4 views
2
a = "[abc]def - aaa"  # key = "abc" value = "def - aaa" 
a2 = "[_abc def]def - aaa" # key = "_abc def" value = "def - aaa" 
b = "[abc]" 
c = "abc]"     # key = "abc" value = "" 
d = "[abc]]def/acd"  # key = "abc" value = "def/acd" 
f = "abc]]"    # key = "abc" value = "" 

Выше приведены лишь некоторые примеры шаблонов. У меня есть тысячи подобных строковых переменных. Кронштейн может быть одинарным "]", "[" или двойной "]]", "[[", или отсутствует в левой части.Регулярное выражение для извлечения ключа, окруженного скобками

Я хочу получить пару ключевых значений. Ключом является строка внутри скобки (может отсутствовать левая скобка) (например, abc, abc def). Значение представляет собой строку в правой части скобки, такую ​​как def - aaa или def/acd, или пустую строку.

Как определить шаблон регулярного выражения в Python? Я попробовал несколько, но они не работают для всех переменных.

Я попытался re.search(r"([^[].*?)(?:]|]])([^]].*)", a), но он не работает с re.search(r"([^[].*?)(?:]|]])([^]].*)", b)

+3

Я не понимаю ваш вопрос. –

+0

Что вы ожидаете от этих примеров? Что делать, например, '' abc]] "? – dawg

+0

@dawg Я обновляю свой вопрос, для '' abc]] "' 'key = abc' и' value = "" ' – Sean

ответ

2

Если вы хотите игнорировать скобки, то вы можете использовать это:

words = re.split('[\[\]]+', key_value) 
words = filter(None, words)   # remove empty words 
key = words[0] 
value = words[1] if len(words) > 1 else None 

Эта модель была скопирована из документации: re — Regular expression operations

+0

Спасибо за ваш ответ, я только что обновил свой вопрос, чтобы он дал понять. – Sean

1

Я бы использовал rpartition здесь:

txt='''\ 
[abc]def - aaa 
[_abc def]def - aaa 
[abc] 
abc] 
[abc]]def/acd 
abc]]''' 

import re 

for e in txt.splitlines(): 
    li=e.rpartition(']') 
    key=re.search(r'([^\[\]]+)', li[0]).group(1) 
    value=li[-1] 
    print '{:20}=> "{}":"{}"'.format(e,key, value) 

Если вы хотите использовать регулярное выражение, вы можете использовать:

for e in txt.splitlines(): 
    m=re.search(r'\[*([^\[\]]+)\]*(.*)', e) 
    print '{:20}=> "{}":"{}"'.format(e,*m.groups()) 

В любом случае, напечатает:

[abc]def - aaa  => "abc":"def - aaa" 
[_abc def]def - aaa => "_abc def":"def - aaa" 
[abc]    => "abc":"" 
abc]    => "abc":"" 
[abc]]def/acd  => "abc":"def/acd" 
abc]]    => "abc":"" 
+0

Спасибо за ваш ответ! – Sean

2

Peronally Я хотел бы сделать это с помощью .index(), но вы просили для регулярного выражения, так что вы здесь.

>>> expr = r"^(?:\[?)(.*?)\]+(.*?)$" 
>>> re.search(expr, a).group(0, 1, 2) 
('[abc]def - aaa', 'abc', 'def - aaa') 
>>> re.search(expr, a2).group(0, 1, 2)   
('[_abc def]def - aaa', '_abc def', 'def - aaa') 
>>> re.search(expr, b).group(0, 1, 2) 
('[abc]', 'abc', '') 
>>> re.search(expr, c).group(0, 1, 2) 
('abc]', 'abc', '') 
>>> re.search(expr, d).group(0, 1, 2) 
('[abc]]def/acd', 'abc', 'def/acd') 
>>> re.search(expr, f).group(0, 1, 2)   
('abc]]', 'abc', '') 

Смотрите в разделе "Информация Match" на правой боковой панели here.

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