[英]Python Regex Scrape & Replace String
Hi i would like to code me a small helper Tool in Python it should process the following content: 嗨,我想用Python编写一个小的辅助工具,它应该处理以下内容:
<tr>
<td><p>L1</p></td>
<td><p>(4.000x2.300x500; 4,6m³)</p></td>
<td><p> </p></td>
<td><p> 1.221 kg</p></td>
</tr>
<tr>
<td><p>L2</p></td>
<td><p>(4.250x2.300x500; 4,9m³)</p></td>
<td><p> </p></td>
<td><p> 1.279 kg</p></td>
</tr>
<tr>
<td><p>L3</p></td>
<td><p>(4.500x2.300x500; 5,2m³)</p></td>
<td><p> </p></td>
<td><p> 1.321 kg</p></td>
</tr>
<tr>
<td><p>L4</p></td>
<td><p>(4.750x2.300x500; 5,5m³)</p></td>
<td><p> </p></td>
<td><p> 1.364 kg</p></td>
</tr>
It should replace the
它应该替换
of each table row with the the volume in this case everthing between the ; 每个表格行的容量(在这种情况下都是介于两者之间); and the ) in the second table data field of each row.
以及每行第二个表格数据字段中的)。
i started to code it in python like that and i could allready scrape the Volume with a regex statement but my logic ends on how to put the values on the right place. 我开始用python这样编写代码,并且可以用regex语句抓取Volume,但是我的逻辑结束于如何将值放在正确的位置。 any idea ?
任何想法 ? here is my code
这是我的代码
import BeautifulSoup
import re
with open('3mmcontainer.html') as f:
content = f.read()
f.close()
#print content
contentsoup = BeautifulSoup.BeautifulSoup(content)
for tablerow in contentsoup.findAll('tr'):
inhalt = str(tablerow.contents[3])
print inhalt
match = re.findall('\;(.*?)\)', inhalt)
print match
# for x in match:
# volumen = x.lstrip()
# print volumen
#f = open('3mmcontainer.html', 'w')
#newdata = f.replace(" ", volumen)
#f.write(newdata)
#f.close()
#m = re.search('\;(.*?)\)', inhalt)
# print m
# volumen = re.compile(r'\;(.*?)\)')
# volumen.match(tablerow.contents[3])
NB: you don't need to call close()
because the with
statement will do it for you. 注意:您不需要调用
close()
因为with
语句将为您完成此操作。
You can use a simple function to transform each row ( <tr/>
): 您可以使用一个简单的函数来转换每一行(
<tr/>
):
import re
def parse_inhalt(content):
td_list = re.findall(r"<td>(?:(?!</td>).)+</td>", content)
vol_content = td_list[1]
vol = re.findall(r";([^)]+)", vol_content)[0]
return content.replace(" ", vol)
The code is straightforward: 代码很简单:
td_list
td_list
每个单元格
by the volume For instance: 例如:
inhalt = u"""\
<tr>
<td><p>L4</p></td>
<td><p>(4.750x2.300x500; 5,5m³)</p></td>
<td><p> </p></td>
<td><p> 1.364 kg</p></td>
</tr>"""
print(parse_inhalt(inhalt))
You get: 你得到:
<tr>
<td><p>L4</p></td>
<td><p>(4.750x2.300x500; 5,5m³)</p></td>
<td><p> 5,5m³</p></td>
<td><p> 1.364 kg</p></td>
</tr>
You can drop the spaces by using: 您可以使用以下命令删除空格:
vol = re.findall(r";\s*([^)]+)", vol_content)[0]
An alternative approach. 另一种方法。
First, find all of the table cells, and the p
elements within them. 首先,找到所有表单元格,以及其中的
p
元素。 You know that the p
elements are characterised by the presence of m³ within their text
s, so watch for them, and you know that you must change the p
elements that follow immediately. 你知道
p
元素由立方米他们中存在表征text
S,所以看他们,你知道你必须改变p
是紧跟元素。 Then arrange to capture the area when you encounter it, note the ordinal number of the p
element and then when you encounter the next p
element, change its text
by assigning area
to its string
attribute. 然后安排在遇到该区域时捕获该区域,记下
p
元素的序号,然后在遇到下一个p
元素时,通过将area
分配给它的string
属性来更改其text
。
If you prefer regex then you could use this for calculating area
: 如果您更喜欢正则表达式,则可以使用它来计算
area
:
area = bs4.re.search(r';\s+([^\)]+)', p.text).groups(0)[0]
. 。
>>> import bs4
>>> soup = bs4.BeautifulSoup(open('temp.htm').read(), 'lxml')
>>> k = None
>>> for i, p in enumerate(soup.select('td > p')):
... if 'm³' in p.text:
... area = p.text[1+p.text.rfind(';'):-1].strip()
... k = i
... if k and i == k + 1:
... p.string = area
...
>>> soup
<html><body><tr>
<td><p>L1</p></td>
<td><p>(4.000x2.300x500; 4,6m³)</p></td>
<td><p>4,6m³</p></td>
<td><p> 1.221 kg</p></td>
</tr>
<tr>
<td><p>L2</p></td>
<td><p>(4.250x2.300x500; 4,9m³)</p></td>
<td><p>4,9m³</p></td>
<td><p> 1.279 kg</p></td>
</tr>
<tr>
<td><p>L3</p></td>
<td><p>(4.500x2.300x500; 5,2m³)</p></td>
<td><p>5,2m³</p></td>
<td><p> 1.321 kg</p></td>
</tr>
<tr>
<td><p>L4</p></td>
<td><p>(4.750x2.300x500; 5,5m³)</p></td>
<td><p>5,5m³</p></td>
<td><p> 1.364 kg</p></td>
</tr></body></html>
>>>
if brute force regex is acceptable 如果可以使用蛮力正则表达式
s='''
<tr>
<td><p>L1</p></td>
<td><p>(4.000x2.300x500; 4,6m³)</p></td>
<td><p> </p></td>
<td><p> 1.221 kg</p></td>
</tr>
<tr>
<td><p>L2</p></td>
<td><p>(4.250x2.300x500; 4,9m³)</p></td>
<td><p> </p></td>
<td><p> 1.279 kg</p></td>
</tr>
<tr>
<td><p>L3</p></td>
<td><p>(4.500x2.300x500; 5,2m³)</p></td>
<td><p> </p></td>
<td><p> 1.321 kg</p></td>
</tr>
<tr>
<td><p>L4</p></td>
<td><p>(4.750x2.300x500; 5,5m³)</p></td>
<td><p> </p></td>
<td><p> 1.364 kg</p></td>
</tr>
'''
import re
p=r'(\([0-9x.]+)(; +)([0-9,m³]+)(\)</p></td>\n <td><p>)( )'
# not sure which output is preferred
x = re.sub(p, '\g<1>\g<2>\g<3>\g<4>\g<3>', s)
print(x)
y = re.sub(p, '\g<1>\g<4>\g<3>', s)
print(y)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.