如何使用模块re在文件中查找关键字

时间:2016-02-18 14:56:26

标签: python python-2.7 python-3.x

我希望制作一个可以使用模块重新从文件中挑选汽车信息的程序。向用户询问有关他想要查看的汽车的问题,如果输入不在文件中,我应该显示错误消息并在用户想要时再次循环代码。我在尝试查找文件中的输入时遇到困难:到目前为止这是代码:

import re
import random


myList = ([])
car = input("What car do you want to view?");
myList.insert(1, car)

model = input("What car model is it of");
myList.insert(2, model)

fuelTy = input("What fuel type is it: diseal or petrol");
myList.insert(3, fuelTy)

engSize = input("What engine size is it : eg 2l");
myList.insert(4, engSize)

rnd = (int(random.randrange(50000000)) + 1)

with open("car.txt", "r") as carfile:
        for line in carfile:
            if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
                splitted_line = line.split(':')
                print(splitted_line)

        if not myList not in carfile:
            print("We don't have the car available currently. Please contact the head office with the case number  " + str(rnd))

            Cho2 = input("Would you like to see anything yes or no").lower
            if Cho2 == "yes":
                print("OK")

            elif Cho2 == "no":
                print("End of program")

文本文件是:         宝马:X6:3.4l:发动机尺寸4395cc:汽油:4.8s内0-62mph:自动变速箱:5门:经济型29mpg:最高时速155 mph         奥迪:Q7:3.0l:发动机尺寸2967cc:发动机:6.5s内0-62mph:自动变速箱:5门:经济型:48mpg:最高时速145 mph          本田:CRV:2.0l:发动机尺寸1997cc:汽油:10.0s内0-62mph:齿轮式手动:5门:经济型30mpg:最高时速18 mph

2 个答案:

答案 0 :(得分:0)

你有错误!

首先,您要将myList = ([])初始化为包含单个空列表的元组,因此append()insert()无法正常工作。试试myList = []

其次,您的myList.insert(...)语句中的索引错误。只需使用myList.append(...)代替,无需担心索引。

然后,尝试替换(未测试......):

if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):

... with:

if all (item.lower() in re.findall('\w+', line.lower()) for item in myList):

一个简单的优化,它也使代码更具可读性:

line_words = set(re.findall('\w+', line.lower()))
if all(item.lower() in line_words for item in myList):

答案 1 :(得分:0)

if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):

在这一行中,您将myList重新定义为文件中的一行。但是你有一个外环(for line in carfile)可以做同样的事情。

更改此项以消除for表达式,您将走上正确的轨道:

if all(myList.lower() in re.findall('\w+', line.lower())):

FWIW,这将是非常重要的,因为您在文件中使用的引擎大小使用不同的度量(cc vs. l)。

接下来,请注意,您可以(并且可能应该避免错误)使用.append()来增加列表,而不是.insert()。区别在于append不要求您跟踪索引,在这种情况下,这样做不会使您受益(您不会随时使用位置信息)并且是错误的来源如果您复制/粘贴代码块以添加新字段。

myList.append(engSize)  # was myList.insert(4, engSize)

此外,您可能应该为用户提供不输入字段的选项,如果他们没有输入字段,则跳过搜索。 (如果字段是空的,也许不要附加字段?)

engSize = input("What engine size is it : eg 2l")
if engSize: myList.append(engSize)

修改

好的,刚刚结束这一天,回到这个节目。 : - )

还有一些问题,但让我们来处理“all需要一个可迭代的issue first. If you look at the docs for [全部`](https://docs.python.org/3/library/functions.html#all),它说

  

all( 迭代 )

因此我们需要重新构建测试以使all成为可迭代的(列表,元组,视图或其他可以迭代的表达式),或者我们需要停止使用all

好吧,我们正在尝试迭代myList,因此可以提出一个可迭代的。让我们从头开始:

if all(s for s in myList):

事实上,我们可以将.lower()放回去 - 这是有道理的。所以:

if all(s.lower() for s in myList):

现在,让我们将s.lower()视为单词(它是)并在输入行中搜索它。我们正在做的是将我们之前的字符串表达式s.lower()转换为布尔表达式:列表中的单词,在我们已经拥有的迭代的上下文中。这将是in关键字的另一种风格:

if all( (EXPR) for s in myList):

if all((s.lower() in re.findall('\w+', line.lower())) for s in myList):

当我做出这个改变时,我可以匹配汽车的品牌。

逻辑也存在一些问题。您希望将用户查询与汽车类型相匹配。如果你不能匹配,那么你想要打印一条关于“我们没有车......”的消息但是你不能在一行中得到那个测试(不匹配)。如果你可以将测试放到一行,你也可以将搜索部分放到一行。 (并非总是如此,但值得一看!)

相反,只需跟踪你是否找到了这辆车:

found_car = False
for line in carfile:
    if ...
        found_car = True
        break

if not found_car:
    print("We don't have the car ...")

接下来,让我们让程序运行更长时间(如果没有别的话,进行测试)。你正在进行for循环,所以我假设你可以进行while循环。让我们在整个过程中添加一个循环,直到用户输入quit

while True:
    make = input("What make of car do you want (or type 'quit')? ")
    if make == 'quit':
        break
    if make: 
        myList.append(make)

最后,让我们来看看你的正则表达式。您正在使用\w+,它将匹配“单词字符”(无论是什么字符)一次或多次。

对于像“audi”和“honda”这样的事情来说,这是一个良好的开端,但单词字符不包括句点('。')或连字符(' - '),它们都出现在您的数据中。 / p>

相反,尝试更改正则表达式以匹配单词字符或点,一次或多次:

re.findall('[\w.]+', ...)
祝你好运!