2016-02-18 117 views
0

我正在寻找一个程序,可以使用模块re从文件中挑选汽车信息。询问用户关于他想要查看的汽车的问题,并且如果输入不在文件中,我应该显示错误消息并且如果用户想要再次循环代码。我有困难要查找的文件中输入:这是迄今为止代码:如何使用模块re在文件中查找关键字

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.4升:发动机尺寸4395cc:汽油:0-62mph 4.8 s:档位自动:5门:经济型29mpg:最高时速155 mph audi:Q7:3.0l:发动机尺寸2967cc:反应:0-62mph 6.5s:档位自动:5门:经济:48mpg:最高速度145英里/小时 本田:CRV:2.0l:发动机大小1997cc:汽油:10.0s:0-62mph:齿轮式手动:5门:经济30mpg:最高时速18英里每小时

+0

你的文件看起来像一个“:”分隔的文件。试试'str.split(“:”)'来看看你是否可以得到一个好的列表,然后查找你想要的元素的索引。如果你有一个标题行,你可以使用'namedtuple'来存储每一行​​。否则,我建议你使用http://pythex.org并自己提出正则表达式作为练习。但是我怀疑你毕竟需要'重新'。 – Mai

+0

但是代码不起作用,即使您输入BMW X6也只打印本田信息,所以我可以帮助解决。 –

回答

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

在这一行中,你是r e定义myList是文件中的一行。但是你有一个外部循环(for line in carfile)可以做同样的事情。

更改为消除表达,你会在正确的轨道上:

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

FWIW,这将是非常冒险的,因为你喜欢的事情发动机尺寸在文件中使用不同的度量(cc对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 [ all`(https://docs.python.org/3/library/functions.html#all),它说

all(iterable)

因此,我们需要调整测试给all可迭代(列表,元组,视图,或其他可以重复表达),否则就要停止使用all

好了,我们正试图遍历myList,所以应该有可能C用可迭代的方式实现。让我们开始考虑到这一点:

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”这样的东西来说,这是一个好的开始,但是单词字符不包括句点('。')或连字符(' - '),它们都会出现在您的数据中。

相反,尝试改变你的正则表达式匹配任何单词字符或点,一次或多次:

re.findall('[\w.]+', ...) 

祝你好运!

+0

这是非常有用的@奥斯汀黑斯廷斯 –

+0

我会尝试和使用它在我的代码,我会告诉你,如果它的工作 –

+0

回溯(最近的通话最后): 如果所有(myList.lower()inre.findall('\ w +',line.lower())): AttributeError:'文件“F:\ car file.py”,第21行,在 列表'对象没有属性'低' >>> –

0

您有错误!

首先,您将myList = ([])初始化为包含单个空列表的元组,因此append()insert()不会起作用。尝试myList = []

其次,您在myList.insert(...)声明中发现索引错误。只需使用myList.append(...)即可,无需担心索引。

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

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

...与:

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): 
+0

谢谢,我会给它一个 –

+0

对不起,但它似乎并没有工作 –

相关问题