Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用csv文件检索和检查python中的密码_Python_Regex_Email_Csv_Line - Fatal编程技术网

使用csv文件检索和检查python中的密码

使用csv文件检索和检查python中的密码,python,regex,email,csv,line,Python,Regex,Email,Csv,Line,我正在尝试编写一个代码,要求输入电子邮件和密码(不是出于任何特殊目的),并将其与包含几行的csv文件进行核对。每行包含一封电子邮件和密码以及一些虚构的客户详细信息。我正在尝试编写一个代码,它接受电子邮件地址和密码(5-12个字符长),然后在文件中搜索包含电子邮件和密码的行,并打印整行(包括客户详细信息)。以下是我到目前为止的代码(这里的一些缩进可能看起来有点奇怪,但实际上只是代码块缩进的结果): 如果我输入了一个故意错误的密码(例如字母“x”),而它恰好存在于另一行上,它将打印该行,尽管它不包含

我正在尝试编写一个代码,要求输入电子邮件和密码(不是出于任何特殊目的),并将其与包含几行的csv文件进行核对。每行包含一封电子邮件和密码以及一些虚构的客户详细信息。我正在尝试编写一个代码,它接受电子邮件地址和密码(5-12个字符长),然后在文件中搜索包含电子邮件和密码的行,并打印整行(包括客户详细信息)。以下是我到目前为止的代码(这里的一些缩进可能看起来有点奇怪,但实际上只是代码块缩进的结果):

如果我输入了一个故意错误的密码(例如字母“x”),而它恰好存在于另一行上,它将打印该行,尽管它不包含电子邮件地址

以下是一个例子:

欢迎访问我们的网站!要访问您的客户详细信息,我们首先要求您登录

电邮地址:ojones@coldmail.net

密码:x

谢谢大家!!以下是您的客户详细信息:

"miguel5@bluebell.net位于牛津市藤蔓大道45号桑托斯米格尔幸福3号,OX7 3RF'

尽管它使用正确的密码工作:

欢迎访问我们的网站!要访问您的客户详细信息,我们首先要求您登录

电邮地址:ojones@coldmail.net

密码:ocrabc

谢谢大家!!以下是您的客户详细信息:

"ojones@coldmail.net,奥克拉巴,奥利弗,琼斯,朴茨茅斯淡水河谷大厦53号,P03 2TD'

还有这个正则表达式,因为我不知道如何将密码长度限制为5-12个字符(我对regex不熟悉,也没有人教过如何使用它):

if re.match(“\A(?P[\w\-\u]+)\ Z”,密码,re.IGNORECASE)
我怀疑,解决这个问题可能主要解决前一个问题(除非有人知道文件的内容),尽管如果可能的话,我们会对此提供一些帮助

可能还有其他问题我还没有意识到,但据我所知,就是这样


我知道这个问题很长,所以感谢您花时间阅读,如果您有任何答案,我们将不胜感激

您的代码当前所做的是在文件上循环两次:每个[f.split()中的行对行]是一个单独的循环。第一个循环获取电子邮件匹配的行列表,第二个循环获取密码匹配的行列表

然后使用“and”操作符将这两个列表合并。Python允许您这样做,如果两个列表都不是空的,则结果将为真,否则为假。由于您试图将操作结果与[]进行比较,因此比较将始终失败

正确的做法是使用一个循环,同时检查两个条件,Python列表理解允许您执行以下操作:

[line for line in f.split() if email in line and password in line]
但是,由于这是一个子字符串检查,因此当用户正确输入密码的一部分时,这将匹配,这通常不是检查密码时所需的。相反,您应该检查整个字符串:

line.startswith(email + "," + password + ",")

回答简单的长问题。不要对列表串联使用布尔运算“和”。使用+将生成正确的列表。“和”的作用-它将每个操作数强制转换为布尔真/假,如果两个列表均为非空,则返回最后一个操作数。否则它将返回[](在您的情况下不会发生)。

下面是一个简单的实现,用于搜索CSV文件中的特定字符串:


我还没有测试过这个,仅供参考。

这是一个经过清理的版本:

import csv
from collections import namedtuple
from itertools import repeat
import re
import sys

EMAIL_REG    = re.compile("^([\w\-_]+@[\w\-_]+\.[\w]+)$", re.IGNORECASE)
PASSWORD_REG = re.compile("^([\w\-_]{5,12})$", re.IGNORECASE)
PASSWORD_CSV = 'A453_datafile_4_Mat 4 Data File.csv'

# define a User type
#   (the field names should match the columns from the .csv file)
User = namedtuple("User", ["email", "password", "firstname", "lastname", "address", "city", "postalcode"])
# prettier output
User.__str__ = lambda self: "{} {}: {} ({} {}, {})".format(self.firstname, self.lastname, self.email, self.address, self.city, self.postalcode)

def all_users_from_csv(fname, **kwargs):
    """
    Return an iterable of Users from the specified csv file
    """
    with open(fname) as in_file:
        for row in csv.reader(in_file, **kwargs):
            yield User(row)

def match_user(users, email, password):
    """
    Return the first user in users who matches the specified email and password;
      on failure, return None
    """
    for user in users:
        if user.email == email and user.password == password:
            return user
    return None

def input_match(prompt, reg, max_tries=None):
    """
    Prompt for input that matches reg;
      on success, return first match group
      on failure, try again (up to max_tries times, if specified)
      on max_tries failures, return None
    """
    if max_tries is None:
        # not specified - repeat forever
        tries = repeat(None)
    else:
        # repeat specified number of times
        tries = range(max_tries)

    for i in tries:
        s = input(prompt)
        m = reg.match(s)
        if m:
            return m.groups(0)

    # if max_tries exceeded
    return None

def do_signin():
    email = input_match("Email address: ", EMAIL_REG, 2)
    if email is None:
        print("You did not enter a valid email address. Good-bye!")
        return None

    password = input_match("Password: ", PASSWORD_REG, 2)
    if email is None:
        print("You did not enter a valid password. Good-bye!")
        return None

    users = all_users_from_csv(PASSWORD_CSV)
    return match_user(users, email, password)

def main():
    print("Welcome to our website! To access your customer details, we first require you to sign in.\n")

    user = do_signin()
    if user is None:
        print("Sorry, your email or password is invalid.")
    else:
        print("Thank you! Here are your customer details:\n")
        print(user)

if __name__=="__main__":
    main()
以及一些评论:

  • 请注意,每次要匹配用户时,它都必须比较(最多).csv文件中的每一行;这既慢又浪费。几乎任何数据库都允许您对电子邮件和密码字段进行索引,从而使其更加高效

  • 我将代码拆分为单独的函数;每个功能都很简单,只有一个特定的用途。命名常量、良好的函数名、docstring和注释——它们都使您的程序更易于理解、测试和以后修改


  • 呃——不要以明文形式存储密码……不介意我问,为什么没有数据库?@Jesse W at Z-它们不是真正的密码,所有信息都是为了这个程序而编造的。@Stefanch-数据库?我需要吗?你必须为索尼工作。谢谢!我以前没有使用过和,我认为在这种情况下它可能比+更合适,显然下次我应该两种都尝试!谢谢,这真的很有帮助。我不知道如何检查整个字符串。
    [line for line in f.split() if email in line and password in line]
    
    line.startswith(email + "," + password + ",")
    
    f = open('A453_datafile_4_Mat 4 Data File.csv', 'r').read() 
    rows = re.split('\n', f.decode())
    
    for index, row in enumerate(rows):
        cells = row.split(',')
        if ('USER_EMAIL_HERE' in cells) and ('USER_PASSWORD_HERE' in cells):
            #Do stuff here
    
    import csv
    from collections import namedtuple
    from itertools import repeat
    import re
    import sys
    
    EMAIL_REG    = re.compile("^([\w\-_]+@[\w\-_]+\.[\w]+)$", re.IGNORECASE)
    PASSWORD_REG = re.compile("^([\w\-_]{5,12})$", re.IGNORECASE)
    PASSWORD_CSV = 'A453_datafile_4_Mat 4 Data File.csv'
    
    # define a User type
    #   (the field names should match the columns from the .csv file)
    User = namedtuple("User", ["email", "password", "firstname", "lastname", "address", "city", "postalcode"])
    # prettier output
    User.__str__ = lambda self: "{} {}: {} ({} {}, {})".format(self.firstname, self.lastname, self.email, self.address, self.city, self.postalcode)
    
    def all_users_from_csv(fname, **kwargs):
        """
        Return an iterable of Users from the specified csv file
        """
        with open(fname) as in_file:
            for row in csv.reader(in_file, **kwargs):
                yield User(row)
    
    def match_user(users, email, password):
        """
        Return the first user in users who matches the specified email and password;
          on failure, return None
        """
        for user in users:
            if user.email == email and user.password == password:
                return user
        return None
    
    def input_match(prompt, reg, max_tries=None):
        """
        Prompt for input that matches reg;
          on success, return first match group
          on failure, try again (up to max_tries times, if specified)
          on max_tries failures, return None
        """
        if max_tries is None:
            # not specified - repeat forever
            tries = repeat(None)
        else:
            # repeat specified number of times
            tries = range(max_tries)
    
        for i in tries:
            s = input(prompt)
            m = reg.match(s)
            if m:
                return m.groups(0)
    
        # if max_tries exceeded
        return None
    
    def do_signin():
        email = input_match("Email address: ", EMAIL_REG, 2)
        if email is None:
            print("You did not enter a valid email address. Good-bye!")
            return None
    
        password = input_match("Password: ", PASSWORD_REG, 2)
        if email is None:
            print("You did not enter a valid password. Good-bye!")
            return None
    
        users = all_users_from_csv(PASSWORD_CSV)
        return match_user(users, email, password)
    
    def main():
        print("Welcome to our website! To access your customer details, we first require you to sign in.\n")
    
        user = do_signin()
        if user is None:
            print("Sorry, your email or password is invalid.")
        else:
            print("Thank you! Here are your customer details:\n")
            print(user)
    
    if __name__=="__main__":
        main()