2009-10-25 80 views
1

嘿,我有一個關於正則表達式的基本問題。我只想返回包含body標籤的文本,並且我知道以下內容不正確,因爲它也會匹配打開body標籤之前的所有字符。我想知道你將如何跳過這些?Python RegEx跳過前幾個字符?

x = re.match('(.*<body).*?(</body>)', fileString) 

謝謝!

+1

你意識到括號指定組,對吧?因此'x.groups()'將只包含標籤。這是你的意圖嗎?也許你的意思是're.match('。* (。*)')'而不是? – 2009-10-25 13:21:14

+0

如果沒有車身標籤,你想匹配什麼? '<!DOCTYPE html>示例

某些文本

'將被任何可用的HTML 5解析器正確解析,但不會被正則表達式正確解析。 – 2009-10-25 13:24:31

+0

@mikem,是的,那就是我的意思。 @peter我將忽略這些頁面。我正在處理已經建好的一組標準頁面。感謝您指出,雖然! – Simon 2009-10-26 11:28:16

回答

2

這裏是一些使用正則表達式來查找<body>...</body>標籤之間的所有文本的代碼示例。雖然這演示了python的re模塊的一些功能,但請注意,Beautiful Soup模塊非常易於使用,並且如果您打算解析HTML或XML,則它是更好的工具。 (見下文對你怎麼可以這樣解析使用BeautifulSoup的例子。)

#!/usr/bin/env python 
import re 

# Here we have a string with a multiline <body>...</body> 
fileString='''baz<body>foo 
baby foo 
baby foo 
baby foo 
</body><body>bar</body>''' 

# re.DOTALL tells re that '.' should match any character, including newlines. 
x = re.search('(<body>.*?</body>)', fileString, re.DOTALL) 
for match in x.groups(): 
    print(match) 
# <body>foo 
# baby foo 
# baby foo 
# baby foo 
# </body> 

如果要收集所有的比賽,你可以使用re.findall:

print(re.findall('(<body>.*?</body>)', fileString, re.DOTALL)) 
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>'] 

,如果您打算使用這種模式不止一次,你可以預先編譯:

pat=re.compile('(<body>.*?</body>)', re.DOTALL) 
print(pat.findall(fileString)) 
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>'] 

這裏是你如何能與BeautifulSoup做到這一點:

#!/usr/bin/env python 
from BeautifulSoup import BeautifulSoup 

fileString='''baz<body>foo 
baby foo 
baby foo 
baby foo 
</body><body>bar</body>''' 
soup = BeautifulSoup(fileString) 
print(soup.body) 
# <body>foo 
# baby foo 
# baby foo 
# baby foo 
# </body> 

print(soup.findAll('body')) 
# [<body>foo 
# baby foo 
# baby foo 
# baby foo 
# </body>, <body>bar</body>] 
+0

+1對於findall(我經常發現比搜索更容易使用),並且因爲我無法弄清楚爲什麼某人低估了 – foosion 2009-10-25 15:27:45

+0

+1 findall對於正則表達式是一個非常方便的解決方案,但正如您所說,BeautifulSoup解析HTML – 2009-10-25 17:36:23

+0

的更好解決方案默認情況下,DOT與新行字符不匹配:值得一提的是,body-tags幾乎總是跨越多行。但是,正如你已經說過的那樣:一個html解析器將是一條可行的路。 – 2009-10-25 18:36:21

-2
x = re.match('.*(<body>.*?</body>)', fileString) 

考慮用於HTML解析的minidom。

+0

minidom解析XML。 HTML!= XML。 – habnabit 2011-09-02 00:54:26

-2
x = re.search('(<body>.*</body>)', fileString) 
x.group(1) 

少打字比匹配回答

9

我不知道Python,但這裏有一個簡單的例子使用Beautiful Soup,我經常看到推薦的Python HTML解析一起拋出。

import BeautifulSoup 

soup = BeautifulSoup(fileString) 

bodyTag = soup.html.body.string 

這將(理論上)處理HTML的所有複雜,這與純基於正則表達式,答案非常困難的,因爲它不是什麼正則表達式是專爲。

+0

這可能比使用正則表達式更有用。謝謝! – Simon 2009-10-26 11:28:55

-2

你的fileString是否包含多行?在這種情況下,你可能需要明確指定,或跳過線:

x = re.match(r"(?:.|\n)*(<body>(?:.|\n)*</body>)", fileString) 

,或者更簡單地用re模塊:

x = re.match(r".*(<body>.*</body>)", fileString, re.DOTALL) 

x.groups()[0]應該包含您的字符串,如果x不無。

+0

我可以問爲什麼-1?這就是所要求的。 – RedGlyph 2009-10-25 15:12:25

+0

+1 for re.DOTALL – foosion 2009-10-25 15:23:04

+0

不知道爲什麼-1,因爲DOTALL是一個有效的點(即使在這裏使用正則表達式的整個想法是有問題的),但是現在你已經回到了零。 :) – 2009-10-25 15:23:18

0

你不能用正則表達式解析HTML。 HTML不是一種常規語言。改用像lxml這樣的HTML解析器。