我正在尝试捕获所有“Catalina 320”的实例,因为它们出现在“这些船”字符串之前(参见下面的通用示例)。
我有代码捕获“Catalina 320”的所有实例但我无法弄清楚如何在“这些船”字符串中停止它。
resultsArray = re.findall(r'<tag>(Catalina 320)</tag>', string, re.DOTALL)
任何人都可以帮我解决这个缺失的部分吗?我尝试添加'。+这些船',但它没有用。
Thanks- JD
Blah blah blah
<tag>**Catalina 320**</tag>
Blah
<td>**Catalina 320**</td>
Blah Blah
<tag>**These boats** are fully booked for the day</tag>
Blah blah blah
<tag>Catalina 320</tag>
<tag>Catalina 320</tag>
答案 0 :(得分:3)
你可以用正则表达式来解决这个问题,但是根据你所述问题的方式不需要正则表达式参见结束注释1 。
您应该使用lxml
来解析此...
import lxml.etree as ET
from lxml.etree import XMLParser
resultsArray = []
parser = XMLParser(ns_clean=True, recover=True)
tree = ET.parse('foo.html', parser) # See End-Note 2
for elem in tree.findall("//"):
if "These boats" in elem.text:
break
elif "Catalina 320" in elem.text:
resultsArray.append(ET.tostring(elem).strip())
print resultsArray
执行此操作会产生:
[mpenning@Bucksnort ~]$ python foo.py
['<tag>**Catalina 320**</tag>', '<td>**Catalina 320**</td>']
[mpenning@Bucksnort ~]$
<小时/> 结束注释:
您问题的当前版本没有有效标记,但我认为您有xml或html(这是您在问题的第1版中所拥有的)...我的回答可以处理您的文本as-written,但假设某些类型的结构标记更有意义,所以我使用了以下输入文本,我将其保存为foo.html:
<body>
<tag>Blah blah blah</tag>
<tag>**Catalina 320**</tag>
<tag>Blah<tag>
<td>**Catalina 320**</td>
</tag>Blah Blah </tag>
<tag>**These boats** are fully booked for the day</tag>
<tag>Blah blah blah</tag>
<tag>Catalina 320</tag>
<tag>Catalina 320</tag>
</body>
如果您想更加关注编码问题,可以在使用lxml.soupparser
lxml
作为后备广告
醇>
from lxml.html import soupparser
# ...
try:
parser = XMLParser(ns_clean=True, recover=True)
tree = ET.parse('foo.html', parser)
except UnicodeDecodeError:
tree = soupparser.parse('foo.html')
答案 1 :(得分:2)
如果您的问题没有其他背景,您可以在第一次出现'These boats'
之前进行搜索:
re.findall('Catalina 320', string.split('These boats')[0])
答案 2 :(得分:0)
groups = re.findall(r'(Catalina 320)*.*These boats, r.read(), re.DOTALL)
组中的第一组将包含Catalina 320匹配列表。
答案 3 :(得分:-1)
名称'foo.html'的文件包含
<body>
<tag>Blah blah blah</tag>
<tag>**Catalina 320**</tag>
<tag>Blah<tag>
<td>**Catalina 320**</td>
</tag>Blah Blah </tag>
<tag>**These boats** are fully booked for the day</tag>
<tag>Blah blah blah</tag>
<tag>Catalina 320</tag>
<tag>Catalina 320</tag>
</body>
代码:
from time import clock
n = 1000
########################################################################
import lxml.etree as ET
from lxml.etree import XMLParser
parser = XMLParser(ns_clean=True, recover=True)
etree = ET.parse('foo.html', parser)
te = clock()
for i in xrange(n):
resultsArray = []
for thing in etree.findall("//"):
if "These boats" in thing.text:
break
elif "Catalina 320"in thing.text:
resultsArray.append(ET.tostring(thing).strip())
tf = clock()
print 'Solution with lxml'
print tf-te,'\n',resultsArray
########################################################################
with open('foo.html') as f:
text = f.read()
import re
print '\n\n----------------------------------'
rigx = re.compile('(Catalina 320)(?:(?:.(?!Catalina 320))*These boats.*\Z)?',re.DOTALL)
te = clock()
for i in xrange(n):
yi = rigx.findall(text)
tf = clock()
print 'Solution 1 with a regex'
print tf-te,'\n',yi
print '\n----------------------------------'
ragx = re.compile('(Catalina 320)|(These boats)')
te = clock()
for i in xrange(n):
li = []
for mat in ragx.finditer(text):
if mat.group(2):
break
else:
li.append(mat.group(1))
tf = clock()
print 'Solution 2 with a regex, similar to solution with lxml'
print tf-te,'\n',li
print '\n----------------------------------'
regx = re.compile('(Catalina 320)')
te = clock()
for i in xrange(n):
ye = regx.findall(text, 0, text.find('These boats') if 'These boats' in text else len(text))
tf = clock()
print 'Solution 3 with a regex'
print tf-te,'\n',ye
结果
Solution with lxml
0.30324105438
['<tag>**Catalina 320**</tag>', '<td>**Catalina 320**</td>']
----------------------------------
Solution 1 with regex
0.0245033935877
['Catalina 320', 'Catalina 320']
----------------------------------
Solution 2 with a regex, similar to solution with lxml
0.0233258696287
['Catalina 320', 'Catalina 320']
----------------------------------
Solution 3 with regex
0.00784708671074
['Catalina 320', 'Catalina 320']
我的解决方案中使用正则表达式错误是什么
时代:
lxml - 100%
解决方案1 - 8.1%
解决方案2 - 7.7%
解决方案3 - 2.6%
使用正则表达式不要求文本是XML或HTML文本。
rigx = re.compile('(Catalina 320)(?:(?:.(?!Catalina 320))*These boats.*\Z)?',re.DOTALL)
的解决方案并不好:
这个正则表达式将捕获'Catalina 320'的出现位于'这些船'后如果没有出现'Catalina 320'之前'这些船'< / p>
模式必须是:
rigx = re.compile('(<tag>Catalina 320</tag>)(?:(?:.(?!<tag>Catalina 320</tag>))*These boats.*\Z)?|These boats.*\Z',re.DOTALL)
但与其他解决方案相比,这是一个相当复杂的模式