2015-08-28 4 views
1

Я хочу извлечь некоторую информацию из моих данных.
Regex для разделения строки в groupdict

наиболее полный ряд, может быть, как показано ниже (каждая часть может содержать CJK характер):

0. (event) (tag) [group (artist)] title (form) [addition1] [addition2]

один ряд может быть также:

1. (event) [group (artist)] title (form) [addition1] 

2. [event] [group (artist)] title (form) (addition1) 

3. (tag) [group (artist)] title 

4. [group (artist)] title 

5. title 

6. and something like above, such as 【tag】 [group (artist)] title 【form】 

Как мы видим, самый простой row is just plain text title, Я напишу регулярное выражение, попробуйте подобрать все из них

import re 
regex_patern = ur'([\(\[](?P<event>[^\)\]]*)[\)\]])?\s*([\(\[](?P<type>[^\)\](\)\])]*)[\)\]])?\s*(\[(?P<group>[^\(\]]*)(\((?P<artist>[^\)]*)\))?\])?(?P<title>[^\(\)\[\]]*)([\(\[](?P<from>[^\)\]]*)[\)\]])?(\s*[\(\[](?P<more1>[^\)\]]*)[\)\]])' 

p = re.compile(regex_patern) 

rows= [ 
'(event) (tag) [group (artist)] title (form) [addition1] [addition2]', 
'(event) [group (artist)] title (form) [addition1]', 
'[event] [group (artist)] title (form) (addition1)', 
'(tag) [group (artist)] title', 
'[group (artist)] title', 
'title', 
] 

for r in rows: 
    r = re.search(p, r) 
    print r.groupdict() 

выход:

{u'from': 'form', u'more1': 'addition1', u'artist': 'artist', u'title': ' title ', u'group': 'group ', u'type': 'tag', u'event': 'event'} 
{u'from': 'form', u'more1': 'addition1', u'artist': 'artist', u'title': ' title ', u'group': 'group ', u'type': None, u'event': 'event'} 
{u'from': 'form', u'more1': 'addition1', u'artist': 'artist', u'title': ' title ', u'group': 'group ', u'type': None, u'event': 'event'} 
{u'from': None, u'more1': 'group (artist', u'artist': None, u'title': '', u'group': None, u'type': None, u'event': 'tag'} 
{u'from': None, u'more1': 'group (artist', u'artist': None, u'title': '', u'group': None, u'type': None, u'event': None} 
--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-5-831c548bc3f0> in <module>() 
    15 for r in rows: 
    16  r = re.search(p, r) 
---> 17  print r.groupdict() 

AttributeError: 'NoneType' object has no attribute 'groupdict' 

Результат стал неожиданным из строки 4.
Я думаю re следует искать в середине. сначала найдите [group (artist)] and title, но я не знаю, как писать в регулярном выражении. Или я делаю неправильный путь?

+0

'title' не соответствует регулярному выражению, поэтому у вас есть проблема. Я думаю, 'if r: \t print r.groupdict()' не то, что вы хотите, правильно –

+0

@stribizhev Я хочу получить все атрибуты правильно.Строка 4: u'more1 ':' group (artist ', u'artist', этот атрибут был уже неправильным. – Mithril

+0

Я обновил ответ –

ответ

1

EDIT

Казалось (по крайней мере, на образце вы предоставляете) вы можете правильно соответствовать и группа вся строка:

^(?:(?:^[\[()](?P<event>[^)\]]+)[)\]](?=.+[\])]$)\s)?(?:[(【](?P<tag>(?<=^[(【])[^】)]+(?=.+[\w】]$)|(?<=\)\s\()[^)]+(?=\)\s\[))[】)]\s)?\[(?:(?P<group>[^(\]]+)\s+\((?P<artist>[^)]+)\)\])\s+)?(?P<title>[^(\n)【]+)(?:\s*[\(【](?P<form>[^)】]+)[)】](?:\s*[\[(](?P<add>[^\])]+)[\])])?(?:\s*[\[(](?P<add2>[^\])]+)[\])])?)?$ 

DEMO

используется в:

import re 

rows= [ 
'(event) (tag) [group (artist)] title (form) [addition1] [addition2]', 
'(event) [group (artist)] title (form) [addition1]', 
'[event] [group (artist)] title (form) (addition1)', 
'(tag) [group (artist)] title', 
'[group (artist)] title', 
'title', 
] 

p = re.compile(ur'^(?:(?:^[\[()](?P<event>[^)\]]+)[)\]](?=.+[\])]$)\s)?(?:[(【](?P<tag>(?<=^[(【])[^】)]+(?=.+[\w】]$)|(?<=\)\s\()[^)]+(?=\)\s\[))[】)]\s)?\[(?:(?P<group>[^(\]]+)\s+\((?P<artist>[^)]+)\)\])\s+)?(?P<title>[^(\n)【]+)(?:\s*[\(【](?P<form>[^)】]+)[)】](?:\s*[\[(](?P<add>[^\])]+)[\])])?(?:\s*[\[(](?P<add2>[^\])]+)[\])])?)?$') 

for r in rows: 
    [m.groupdict() for m in p.finditer(r)] 
    print m.groupdict() 

выдает говоря:

{u'event': 'event', u'tag': 'tag', u'group': 'group', u'artist': 'artist', u'title': 'title ', u'form': 'form', u'add': 'addition1', u'add2': 'addition2'} 
{u'event': 'event', u'tag': None, u'group': 'group', u'artist': 'artist', u'title': 'title ', u'form': 'form', u'add': 'addition1', u'add2': None} 
{u'event': 'event', u'tag': None, u'group': 'group', u'artist': 'artist', u'title': 'title ', u'form': 'form', u'add': 'addition1', u'add2': None} 
{u'event': None, u'tag': 'tag', u'group': 'group', u'artist': 'artist', u'title': 'title', u'form': None, u'add': None, u'add2': None} 
{u'event': None, u'tag': None, u'group': 'group', u'artist': 'artist', u'title': 'title', u'form': None, u'add': None, u'add2': None} 
{u'event': None, u'tag': None, u'group': None, u'artist': None, u'title': 'title', u'form': None, u'add': None, u'add2': None} 

DEMO

Это регулярное выражение состоит из пары частей:

  • (?:^[\[()](?P<event>[^)\]]+)[)\]](?=.+[\])]$)\s)? - соответствующие события
  • (?:[(【](?P<tag>(?<=^[(【])[^】)]+(?=.+[\w】]$)|(?<=\)\s\()[^)]+(?=\)\s\[))[】)]\s)? - соответствие метки
  • \[(?:(?P<group>[^(\]]+)\s+\((?P<artist>[^)]+)\)\])\s+)? - соответствующие группы
  • (?P<title>[^(\n)【]+) - согласование название
  • (?:\s*[\(【](?P<form>[^)】]+)[)】](?:\s*[\[(](?P<add>[^\])]+)[\])])?(?:\s*[\[(](?P<add2>[^\])]+)[\])])?)? - форма согласования и добавляет

Как вы можете видеть, каждая часть, за исключением части сопрягать title, заканчивается ? квантора, что означает ноль или один. Из-за этого эта часть является необязательной, она будет соответствовать, если есть фрагмент, который соответствует, но если нет, он не будет мешать (по крайней мере, не должен), как будет работать остаток регулярного выражения. Вот почему кажется, что он соответствует «от середины», а не «слева направо».

+0

Вы так хороши! Как вы принудительно повторяете строку из середины? какое-то объяснение? – Mithril

+0

@ Mithril I обновленный ответ :) –

+0

Так много '?' расстраивают меня, что заставило меня надеяться, что есть способ совпадения от середины. Спасибо вам за разъяснение :) . – Mithril

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