如何查询我输入的csv文件的特定列并使用python打印所有返回的行?

时间:2016-03-11 21:16:13

标签: python regex csv

因此,为了引导您完成它,这就是我想要做的事情

1)我想将脚本放在我要分析的csv的文件夹中

2)运行脚本

3)输入我要分析的.csv的名称

4)输入我要搜索的单词和短语,用逗号分隔

5)搜索并打印包含我指定的任何单词/短语的行

好的,这是我的代码

import csv


opening_text = "Make sure this script is in the same folder as file you want to analyze \n"
print opening_text

file_name = raw_input('Enter file name ending with .csv to analyze (e.g. file.csv): ')


print "\n The file that will be analyzed is " + file_name + "\n"

my_terms = raw_input('Please enter the words and phrases you would like to find in ' + file_name + ', separated by a comma:')


single_terms= my_terms.split(',')
with open(file_name, 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        for term in single_terms:
            if term in row:
                print ' '.join(row)

我目前的脚本有这些问题:

1)它没有搜索短语。它可以单独搜索“嘿”和“那里”,但不能搜索“嘿那里”

2)它没有消毒我的输入。例如,我用逗号后跟空格来描述我的术语,但如果我要搜索的下一个短语位于句子的开头,则它不会正确搜索它。

3)如果搜索词与文件内容的案例不同,则会得出错误的结果

此外,有什么办法可以只搜索我的csv文件中的一列吗?例如只需搜索“评论”栏。

以下是“sample.csv”中包含的示例数据,该文件与脚本位于同一文件夹中。

样本数据

Date;Customer Name;Comments

2/12/2015;Eric;The apples were absolutely delicious

3/10/2015;Tasha;I enjoyed the mangoes thoroughly

4/11/2014;Walter;The mangoes were awesome

3/10/2009;Ben;Who killed the cat really

9/10/2088;Lisa;Eric recommended guavas for me

1 个答案:

答案 0 :(得分:0)

对于上述情况,您可能不需要正则表达式;简单的字符串搜索会做。但是,让我们来看看这两个版本。

首先,您使用空格' '作为分隔符,这对于您提供的CSV数据不正确。要正确解析,您需要使用';'作为分隔符。在您的示例中,quotechar没有任何效果,因此您可以省略它或将其设置为常见的。

对于以下两个版本,我使用以下内容:

file = 'sampledata/test.csv' # Target CSV file path
terms = 'enjoy, apples, the mangoes' # You want to replace this with your input

版本1:字符串搜索

lookup = [i.strip().lower() for i in terms.split(',')]
with open(file, 'r') as csvin:
    rdr = csv.reader(csvin, delimiter=';', quotechar='"')
    header = rdr.next()
    for row in rdr:
        for l in lookup:
            if row[header.index('Comments')].lower().find(l) != -1:
                print(row)

为了帮助您完成此操作,以下是基本步骤:

  1. 将输入terms转换为可用的内容。我在你的代码中写道,我把它分成逗号。另外,strip()空格,因为它们会阻止您在评论开头找到某些内容。

  2. 读取文件,设置CSV阅读器并从第一行开始绘制标题。

  3. 对于查找列表中的每一行和每个元素,我们测试查找是否存在于字符串中的某处。我使用lower()来忽略大小写,尤其是在评论开始时。

  4. 我示例性选择输入词的结果是:

    ['2/12/2015', 'Eric', 'The apples were absolutely delicious']
    ['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
    ['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
    ['4/11/2014', 'Walter', 'The mangoes were awesome']
    

    注意:一条评论会返回两次,因为我们在文本中找到了两个查找元素。你无法直接避免这种情况,但你可以事后处理。

    版本2:正则表达式

    上面的大多数例子都是一样的。这是代码:

    lookup = [re.compile(i.strip().lower()) for i in terms.split(',')]
    with open(file, 'r') as csvin:
        rdr = csv.reader(csvin, delimiter=';', quotechar='"')
        header = rdr.next()
        for row in rdr:
            for l in lookup:
                m = l.search(row[header.index('Comments')].lower())
                if m is not None:
                    print(row)
    

    区别在于步骤1和3:

    1. 对于每个输入术语,我们编译一个正则表达式并将其存储在我们的查找列表中。 注意:在我的示例中,正则表达式回退到一些常规字符串搜索,因为没有使用特殊的正则表达式运算符。但是,您可以输入mango(es)?

    2. 之类的内容
    3. (与上述相同)

    4. 对于每一行和每个正则表达式查找,使用re.search()测试CSV的注释列,这会生成正则表达式匹配对象re.MatchObject。如果生成的对象不是None,则表示您找到了匹配项。 注意:使用匹配对象的start()方法访问找到的子字符串的位置。有关更多功能,请参阅Regex Match Objects

    5. 上的文档

      正则表达式版本的结果与上面相同:

      ['2/12/2015', 'Eric', 'The apples were absolutely delicious']
      ['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
      ['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
      ['4/11/2014', 'Walter', 'The mangoes were awesome']
      

      另外...

      您询问是否只能搜索一列。如果从csv阅读器获取一行,它会提供一个由提供的分隔符拆分的字符串列表。要按名称获取特定列,可以在最初绘制的标题行上使用index()函数,然后使用返回的索引访问行列表中的元素。