Python:parse(date)返回有符号整数大于最大值

时间:2014-08-17 07:40:14

标签: python regex

给出如下项目列表(由制表符分隔的列):

  • 9123456780 \ t John Dude \ t地址之城\ t 1980年7月19日\ t M
  • 9123456781 \ t Jane Dudette \ t地址•1980年8月19日\ t f
  • 9123456782 \ t Sam Pol Data \ t Etc. City \ t 1/1/91 \ t
  • 9123456783 \ t May Anaise \ t Some City \ t 1993 \ t f
  • 9123456784 \ t Mark Mywards \ t City of Address \ t M
  • 9123456785 \ t地址城市\ t 1980年7月19日\ t M
  • 9123456780 \ t M
  • Mira Nova \ t City of Address \ t 1970年7月19日

我要确定哪一个是MSISDN(10位数字),姓名,地址,日期和性别。

由于缺乏比较点,并且经常缺少数据,我很确定100%正确/准确地做不到这一点。

所以这就是我所做的:

逐行浏览列表。然后按Tab(\ t)拆分每一行,成为一个列表。 然后在for循环中测试列表中的每个项目:

for item in csv_cols:
    if reg_msisdn.match(item):
        s_msisdn = item
    if item.lower() in list_male or item.lower() in list_female:
        s_gender = item
    if parse(item):
        s_birthdate = item
    if any(ext in item.lower() for ext in list_place) or any(ext in item.lower() for ext in list_ad):
        s_address = item
    else:
        s_name = item

    s_all = s_msisdn + "^" + s_name + "^" + s_address + "^" + s_birthdate + "^" + s_gender

编辑:我在csv_cols.remove(item)之后添加了s_(value) = item,以便已经删除测试项目 - 它没有改变任何内容。

  1. 所有s_(value)都以NULL作为文字
  2. 开始
  3. 如果任何项目是10位数字(正则表达式),则将其视为s_msisdn
  4. 如果任何项目仅为m,f,男性,女性,则视为s_gender
  5. 如果任何项目包含关键字city,ave等(list_ad)与地点列表(list_place)中的项目匹配,则会将其视为s_address。< / LI>
  6. 如果任何项目可以是parsed as a date,则会自动为s_birthdate
  7. 否则,可能 s_name
  8. 编辑:从列表中删除所述项目。
  9. 整个事情都在Try-Exception块中。
  10. 我很确定我的逻辑中会出现明显漏洞,但我无法想到其他任何方法。

    尽管如此,即使有这种分散的逻辑,我也遇到了问题,特别是项目编号。以上5,无效返回以下错误:

    signed integer is greater than maximum

    我知道这一点,因为将其从循环中取出会使代码的其余部分工作。

    我可以帮忙解决这个问题吗?

    感谢。

    P.S。:如果有任何意义,我会使用Mac / UNIX。

3 个答案:

答案 0 :(得分:1)

它试图将您的msisdn解析为日期,这会引发异常而不是返回false,这就是为什么如果解析(...):不起作用的原因。使用像

这样的东西
try:
    parse(item)
    continue
except ValueError:
    pass

(如果它不是ValueError,那么检查抛出的异常类型并使用它)

答案 1 :(得分:1)

几乎不可能在所有情况下区分名称和地址("Jack Street"是名称还是地址?)。最好的方法是假设名称始终出现在地址之前,否则您将面临进行各种复杂查找。

我会逐行处理数据,首先将行转换为如下列表:

>>> row = "9123456780 \t John Dude \t City of Address \t July 19, 1980 \t M"
>>> row = [entry.strip() for entry in row.split("\t")]
>>> row
['9123456780', 'John Dude', 'City of Address', 'July 19, 1980', 'M']

现在我定义了一系列函数来尝试确定每个条目代表什么。确定MSISDN号码,性别和日期应该相对简单。

确定一行中的条目是否为十位数的MSISDN号码:

import re

def is_msisdn(entry):
    if re.match(r"[0-9]{10}", entry):
         return True

确定一行中的条目是否表示性别:

def is_gender(entry):
    if entry in ("m", "f", "M", "F"):
         return True

确定行中的条目是否代表日期:

from dateutil.parser import parse

def is_date(entry):
    try: 
        parse(entry)
        return True
    except ValueError:
        return False

现在使用这些函数构建另一个解析行条目的函数:

def parse_row(row):

    s_all = ["<blank>"] * 5

    for entry in row:

        if is_msisdn(entry):
            s_all[0] = entry

        elif is_gender(entry):
            s_all[4] = entry

        elif is_date(entry):
            s_all[3] = entry

        elif s_all[1] == "<blank>":
            s_all[1] = entry

        else:
            s_all[2] = entry

    return " ^ ".join(s_all)

这给出了例如:

>>> row = ['Mira Nova', 'City of Address', 'July 19, 1980']
>>> parse_row(row)
'<blank> ^ Mira Nova ^ City of Address ^ July 19, 1980 ^ <blank>'

>>> row = ['9123456784', 'Mark Mywards', 'City of Address', 'M']
>>> parse_row(row)
'9123456784 ^ Mark Mywards ^ City of Address ^ <blank> ^ M'

答案 2 :(得分:0)

试试这个:

if reg_msisdn.match(item):
        s_msisdn = item
    elif item.lower() in list_male or item.lower() in list_female:
        s_gender = item
    elif parse(item):
        s_birthdate = item
    elif any(ext in item.lower() for ext in list_place) or 
         any(ext in item.lower() for ext in list_ad):
        s_address = item
    else:
        s_name = item

您可能需要调整测试顺序。这个想法是,一旦项目匹配,其他测试不会应用。这也将提高速度。