给出如下项目列表(由制表符分隔的列):
我要确定哪一个是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
,以便已经删除测试项目 - 它没有改变任何内容。
s_(value)
都以NULL
作为文字s_msisdn
。s_gender
。s_address
。< / LI>
s_birthdate
。s_name
。我很确定我的逻辑中会出现明显漏洞,但我无法想到其他任何方法。
尽管如此,即使有这种分散的逻辑,我也遇到了问题,特别是项目编号。以上5,无效返回以下错误:
signed integer is greater than maximum
我知道这一点,因为将其从循环中取出会使代码的其余部分工作。
我可以帮忙解决这个问题吗?
感谢。
P.S。:如果有任何意义,我会使用Mac / UNIX。
答案 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
您可能需要调整测试顺序。这个想法是,一旦项目匹配,其他测试不会应用。这也将提高速度。