如果HTML元素包含一定数量的数字字符,则将其删除

时间:2018-11-04 11:38:51

标签: python regex parsing

对于使用Python将html格式的文件转换为纯文本文件,如果表中的文本包含40%以上的数字字符,则需要删除所有表。

具体来说,我想:

  1. 标识html文件中的每个表格元素
  2. 计算文本中数字和字母字符的数量以及相应的比率,而不考虑任何html标签中的字符characters。因此,删除所有html标签。
  3. 如果表的文本包含40%以上的数字字符,则将其删除。如果表中的数字字符少于40%,请保留该表。

我定义了一个在运行re.sub命令时调用的函数。 rawtext 变量包含我要解析的整个html格式的文本。在该函数中,我尝试处理上述步骤,并根据数字字符的比例返回表格的html剥离版本或空格。但是,该功能中的 first re.sub命令似乎不仅删除标签,而且还删除所有内容,包括文本内容。

def tablereplace(table):
    table = re.sub('<[^>]*>', ' ', str(table))
    numeric = sum(c.isdigit() for c in table)
    alphabetic = sum(c.isalpha() for c in table)
    try:
            ratio = numeric / (numeric + alphabetic)
            print('ratio = ' + ratio)
    except ZeroDivisionError as err:
            ratio = 1
    if ratio > 0.4:
            emptystring = re.sub('.*?', ' ', table, flags=re.DOTALL)  
            return emptystring
    else:
            return table

rawtext = re.sub('<table.+?<\/table>', tablereplace, rawtext, flags=re.IGNORECASE|re.DOTALL)

如果您对这段代码可能有什么问题有一个想法,请与我分享,我将非常高兴。谢谢!

2 个答案:

答案 0 :(得分:1)

正如我在注释中建议的那样,我不会使用正则表达式来解析和在代码中使用HTML。例如,您可以使用为此目的而构建的python库,例如BeautifulSoup

这里有一个使用方法的例子

#!/usr/bin/python
try:
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup
html = """<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td> 
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td> 
    <td>94</td>
  </tr>
</table>
    </div>
</body>
</html>"""
parsed_html = BeautifulSoup(html, 'html.parser')
print parsed_html.body.find('table').text

所以您最终可能会得到这样的代码(只是为了给您一个想法)

#!/usr/bin/python
import re
try:
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup



def tablereplace(table):
    table = re.sub('<[^>]*>', ' ', str(table))
    numeric = sum(c.isdigit() for c in table)
    print('numeric: ' + str(numeric))
    alphabetic = sum(c.isalpha() for c in table)
    print('alpha: ' + str(alphabetic))
    try:
            ratio = numeric / float(numeric + alphabetic)
            print('ratio: '+ str(ratio))
    except ZeroDivisionError as err:
            ratio = 1
    if ratio > 0.4:
            return True
    else:
            return False

table = """<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>3241424134213424214321342424214321412</td>
    <td>213423423234242142134214124214214124124</td> 
    <td>213424214234242</td>
  </tr>
  <tr>
    <td>124234412342142414</td>
    <td>1423424214324214</td> 
    <td>2134242141242341241</td>
  </tr>
</table>
"""

if tablereplace(table):
        print 'replace table'
        parsed_html = BeautifulSoup(table, 'html.parser')
        rawdata = parsed_html.find('table').text
        print rawdata

更新: 无论如何,这行代码会剥夺所有HTML标记,因为您会知道“因为将其用于字符/数字计数

table = re.sub('<[^>]*>', ' ', str(table))

但这并不安全,因为您还可以在标签的文本中包含<>,否则HTML可能会被破坏或放错位置

我将其保留在原处,因为对于该示例而言,它可以正常工作。但是请考虑将BeautifulSoup用于所有HTML管理。

答案 1 :(得分:0)

谢谢您到目前为止的答复!

经过深入研究,我找到了解决整个比赛神秘删除的方法。似乎该功能仅考虑了比赛的前150个字符。但是,如果指定 table = table.group(0),则会处理整个匹配项。 group(0)在这里占很大的比例。

在下面,您可以找到我的更新脚本,该脚本可以正常工作(还包括一些其他小的更改):

def tablereplace(table):
    table = table.group(0)
    table = re.sub('<[^>]*>', '\n', table)
    numeric = sum(c.isdigit() for c in table)
    alphabetic = sum(c.isalpha() for c in table)
    try: 
        ratio = numeric / (numeric + alphabetic)
    except ArithmeticError:
        ratio = 1
    else:
        pass
    if ratio > 0.4:
        emptystring = ''  
        return emptystring
    else:
        return table 
rawtext = re.sub('<table.+?<\/table>', tablereplace, rawtext, flags=re.IGNORECASE|re.DOTALL)