2017-02-23 63 views
3

我試圖分裂這些行:Python的分裂在標籤的正則表達式

<label>Olympic Games</label> 
<title>Next stop</title> 

分爲:

["<label>", "Olympic Games", "</label>"] 
["<title>", "Next stop", "</title>"] 

在Python,我可以使用正則表達式,但我所做的沒有做什麼:

line.split("<\*>") 
+1

這是XML?爲什麼不使用XML解析器? –

+0

除了@StevenRumbalski,強制性通知這是一個壞主意,因爲正則表達式缺乏足夠的能力來準確地解釋上下文無關文法(例如XML,HTML,平衡的parens)。你被警告了。 –

回答

3

使用lookarounds和捕獲組保持拆分後的文字:

re.split(r'(?<=>)(.+?)(?=<)', '<label>Olympic Games</label>') 
+0

這是更好的使用lookarounds ?,我已經在regexpal嘗試過你的正則表達式,但不支持在javascript或PCRE上。 – elbaulp

+1

@ algui91這在JS中不起作用,因爲它使用向後看,但它應該在PCRE中工作。無論如何,很難說它是否「更好」,這取決於確切的文本OP會使用它,在速度或內存消耗方面不會有顯着差異,但可能您的圖案會匹配我的圖案不會的字符串,或者相反。 –

+0

謝謝Rawnig – elbaulp

3

這正則表達式的工作對我來說:

<(label|title)>([^<]*)</(label|title)> 

,或者如cwallenpoole建議:

<(label|title)>([^<]*)</(\1)> 

enter image description here

我用http://www.regexpal.com/

我已經使用了三個捕獲組,如果你不需要它們,只需刪除()

你的正則表達式錯誤<\*>是匹配只有一件事:<*>。你已經使用\* scaped *,所以你說的是:

  • 匹配任何文字與<,然後*然後>
+1

'[(標題)]([^ <]*)'是更好的 – cwallenpoole

+0

@cwallenpoole你是對的,它是更優雅。更新。 – elbaulp

2

數據:

line = """<label>Olympic Games</label> 
<title>Next stop</title>""" 

憑藉前瞻/向後看斷言與re.findall

import re 

pattern = re.compile("(<.*(?<=>))(.*)((?=</)[^>]*>)") 
print re.findall(pattern, line) 
# [('<label>', 'Olympic Games', '</label>'), ('<title>', 'Next stop', '</title>')] 

沒有外觀,提前/向後看斷言,只是通過捕獲組,re.findall

pattern = re.compile("(<[^>]*>)(.*)(</[^>]*>)") 
print re.findall(pattern, line) 
# [('<label>', 'Olympic Games', '</label>'), ('<title>', 'Next stop', '</title>')] 
0

如果你不介意的標點符號,這裏是用itertools.groupby快速非正則表達式的選擇。

代碼

import itertools as it 


def split_at(iterable, pred, keep_delimter=False): 
    """Return an iterable split by a delimiter.""" 
    if keep_delimter: 
     return [list(g) for k, g in it.groupby(iterable, pred)] 
    return [list(g) for k, g in it.groupby(iterable, pred) if k] 

演示

>>> words = "Lorem ipsum ..., consectetur ... elit, sed do eiusmod ...".split(" ") 
>>> pred = lambda x: "elit" in x 
>>> split_at(words, pred, True) 
[['Lorem', 'ipsum', '...,', 'consectetur', '...'], 
['elit,'], 
['sed', 'do', 'eiusmod', '...']] 

>>> words = "Lorem ipsum ..., consectetur ... elit, sed do eiusmod ...".split(" ") 
>>> pred = lambda x: "consect" in x 
>>> split_at(words, pred, True) 
[['Lorem', 'ipsum', '...,'], 
['consectetur'], 
['...', 'elit,', 'sed', 'do', 'eiusmod', '...']]