2015-08-28 81 views
1

我想從我的數據中提取一些信息。
正則表達式將不同的字符串拆分爲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】 

正如我們看到的,最簡單的行只是純文本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'與正則表達式不匹配,因此您有問題。我猜'如果r: \t print r.groupdict()'不是你想要的,對嗎 –

+0

@stribizhev我想正確地得到所有屬性。第4行:u'more1':'group(artist',u'artist',this attribute was wrong。 – Mithril

+0

I updated answer –

回答

1

編輯

這似乎(至少在樣品您提供的),你可以正確地匹配和組整串用:

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() 

^(?:(?:^[\[()](?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

中使用

發出放:

{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

You are so nice!你如何強制重新匹配中間的字符串?一些解釋? – Mithril

+0

@Mithril我更新了答案:) –

+0

這麼多'?'讓我感到挫敗,這讓我希望有一種方法可以從中間匹配。謝謝你的解釋 :) 。 – Mithril

相關問題