通过正则表达式提取数据并写入CSV,Python glob(pandas?)

时间:2014-02-03 22:14:56

标签: python regex python-2.7 csv pandas

我有一大堆不同脏的CSV,其中包含各种格式的电话号码。我想要的是梳理所有这些并以简单的格式导出到已清理的电话号码的单列CSV。到目前为止,我已经拼凑了一些工作,虽然它有一些问题:(下面进一步部分修订)

import csv
import re
import glob
import string

with open('phonelist.csv', 'wb') as out:
    seen = set()
    output = []
    out_writer = csv.writer(out)
    csv_files = glob.glob('CSVs\*.csv')
    for filename in csv_files:
        with open(filename, 'rbU') as ifile:
            read = csv.reader(ifile)
            for row in read:
                for column in row:
                    s1 = column.strip()
                    if re.match(r'\b\d\d\d\d\d\d\d\d\d\d\b', s1):
                        if s1 not in seen:
                            seen.add(s1)
                            output.append(s1)
                    elif re.search(r'\b\(\d\d\d\) \d\d\d-\d\d\d\d\b', s1):
                        s2 = filter(lambda x: x in string.digits, s1)
                        if s2 not in seen:
                            seen.add(s2)
                            output.append(s2)
    for val in output:
        out_writer.writerow([val])

我把它放在一起没有正式的python知识,只是拼凑我在这个网站上收集到的东西。任何有关pythonic程式化或使用pandas库快捷方式的建议都将受到欢迎。

第一个问题:过滤到匹配值的最简单方法是什么? IE,我可能会得到9815556667 John Smith,但我只想要这个号码。

第二个问题:这需要永远。我认为这是lambda部分。是否有更快或更有效的方法?

第三个问题:我如何在程序目录和CSVs目录中填写* .csv(如所写)?

我立刻就知道了几个问题,但我已经把自己弄到了一半。任何额外的指针都表示赞赏。


例如,请求,这不是来自文件(这些是千兆字节的文件),但这是我正在寻找的:

John Smith, (981) 991-0987, 9987765543 extension 541, 671 Maple St 98402
(998) 222-0011, 13949811123, Foo baR Us, 2567 Appleberry Lane
office, www.somewebpage.com, City Group, Anchorage AK
9281239812
(345) 666-7777

应该成为:

9819910987
9987765543
9982220011
3949811123
3456667777

(我忘记了我需要从11位数字中删除前导1)


编辑:我已经改变了我目前的代码以纳入Shahram的建议,所以现在,从for column in row以上,我有,而不是上面:

for column in row:
    s1 = column.strip()
    result = re.match(
        r'.*(\+?[2-9]?[0-9]?[0-9]?-?\(?[0-9][0-9][0-9]\)? ?[0-9][0-9][0-9]-?[0-9][0-9][0-9][0-9]).*', s1) or re.match(
        r'.*(\+?[2-9]?[0-9]?[0-9]?-?\(?[0-9][0-9][0-9]\)?-?[0-9][0-9][0-9]-?[0-9][0-9][0-9][0-9]).*', s1)
    if result:
        tempStr = result.group(1)
        for ch in ['(', ')', '-', ' ']:
            tempStr = tempStr.replace(ch, '')
        if tempStr not in seen:
            seen.add(tempStr)
            output.append(tempStr)

这似乎适用于我的目的,但我仍然不知道如何对当前目录和子目录进行全局化,而且我仍然不知道我的代码是否存在由于我的大杂烩而我不知道的问题 - 波奇-ING。此外,在我更大的目录中,这是永远的 - 就像在大约20分钟左右,我(通过我的手)关闭一大堆CSV。我不知道它是否会遇到麻烦,但从python通常咀嚼任意数量的CSV的速度来判断,感觉就像我错过了一些东西。

1 个答案:

答案 0 :(得分:1)

关于您的第一个问题,您可以使用以下正则表达式来捕获不同类型的电话号码:

  result = re.match(r'.*(\+?[0-9]?[0-9]?[0-9]?-?\(?[0-9][0-9][0-9]\)?-?[0-9][0-9][0-9]-?[0-9][0-9][0-9][0-9]).*', s1)
  if result:
    if result.group(1) not in seen:
       seen.add(result.group(1))
       output.append(result.group(1))

关于第二个问题:您可能需要查看替换功能。所以上面的代码可以改为:

  result = re.match(r'.*(\+?[0-9]?[0-9]?[0-9]?-?\(?[0-9][0-9][0-9]\)?-?[0-9][0-9][0-9]-?[0-9][0-9][0-9][0-9]).*', s1)
  if result:
    if result.group(1) not in seen:
       tempStr = result.group(1)
       tempStr.replace('-','')
       seen.add(tempStr)
       output.append(tempStr)