【问题标题】:python regex to extract username:password or email:password in mixed delimited csvpython 正则表达式提取混合分隔csv中的用户名:密码或电子邮件:密码
【发布时间】:2019-06-28 05:18:54
【问题描述】:

我有(数千个)csv 文件,其中包含各种(数十亿)行,例如:

combos.csv

example0@domain.tld:passw0rd
ex.a.m-pl_e1@domain.tld;p@££w0r46&
0-0-0 ex.a.m-pl_e1@domain.tld p@££w0r46&
ex.a.m-pl_e1@domain.tld:00-00-00;p@££w0r46& <-- updated line
00-00-00:username:password
username:p@££w0r46&
username p@££w0r46&
and more...

我正在尝试为我正在做的一些机器学习任务提取电子邮件或用户名和密码。但我似乎无法为此确定正确的正则表达式。

使用re.splitre.findallre.search 似乎是这里的选项,我正在尝试编译一个正则表达式,让我可以简单地打印例如:

Email: "example0@domain.tld" Password: "passw0rd"
Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
Username: "username" Password: "password"
Username: "username" Password: "p@££w0r46&"
Username: "username" Password: "p@££w0r46&"

来自以上combos.csv

我已设法将以下内容用于电子邮件/密码组合:

re.compile(r'(?:.*[:|;])?(?P<email>[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)[:|;](?P<Password>.*)')

但提取用户名/密码我还没有管理。我试过后视;和 :但似乎当行被分隔两次时,我当前的正则表达式将返回第一列作为用户名,接下来的两列作为密码:

re.compile(r'^(?:.*[:|;])?(?P<username>[A-z0-9\.\-\_\$\#\&]+)(?!@)[:|;](?P<password>.*)')

我怎样才能正确地做到这一点,更好的是,有没有一个正则表达式可以做所有事情的解决方案?

欢迎任何帮助!

【问题讨论】:

  • 在逐行读取文件时尝试re.search(r'(?P&lt;username&gt;[^;: ]+)[:; ](?P&lt;password&gt;[^;: ]+)$', line).groupdict()
  • 这会在所有情况下丢弃第一列。我试试这个看看能不能用,谢谢!如果您有完整的解决方案,我会非常乐意勾选答案。
  • 在此之前您没有指定玩具需要任何东西。如果您需要该数据,请在开头添加^(?P&lt;start&gt;.*?)。如果不需要分隔符,请使用re.search(r'^(?:(?P&lt;start&gt;.*?)[:; ])?(?P&lt;username&gt;[^;: ]+)[:; ](?P&lt;password&gt;[^;: ]+)$', line).groupdict(),参见ideone.com/PCkmHQ
  • 我很抱歉,我已经更新了我的答案。
  • 我怀疑这是个问题,如果您使用像 (email).*?(pass)|(pass).*?(email) 这样的模式然后弄清楚哪些数据在哪里,这将花费更多时间。

标签: python regex csv


【解决方案1】:

如果您打算从您可能使用的每一行中提取电子邮件、密码和可选的用户名数据

import re
rx = re.compile(r'[:; ]')
rx_email = re.compile(r'\S+@\S+\.\S+$')
with open(your_file, "r") as f:
    for line in f:
        fields = rx.split(line)
        email = ''
        id = ''
        for field in fields:
            if rx_email.match(field):
                email = field
            elif field != fields[-1]:
                id = field
        password = fields[-1]
        print("Username: '{}', email: '{}', password: '{}'".format(id, email, password))

this Python demo

^\S+@\S+\.\S+$ 模式匹配类似电子邮件的字段,以 1+ 个非空白字符开头,然后是 @,再有 1+ 个非空白字符,`。并以 1+ 个非空白字符结尾。

re.split 一起使用的[:; ] 模式用空格分隔,;:

【讨论】:

    【解决方案2】:

    这样的事情怎么样:

    import re
    
    with open('file.csv', 'r') as f:
        rows = f.readlines()
    
    data = [re.split(r'\s|;|:', row) for row in rows]
    # remove the 00-00-00 bits
    clean_data = [filter(lambda x: re.match(r'(0+\-+)+', x) == None, d)[:-1]
                  for d in data]
    
    mail_regex = r'[^@]+@[^@]+\.[^@]+'
    
    for d in clean_data:
        if re.match(mail_regex, d[0]) is not None:
            print 'Email: "{}" Password: "{}"'.format(d[0], d[1])
        else:
            print 'Username: "{}" Password: "{}"'.format(d[0], d[1])
    

    产生:

    Email: "example0@domain.tld" Password: "passw0rd"
    Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
    Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
    Email: "ex.a.m-pl_e1@domain.tld" Password: "p@££w0r46&"
    Username: "username" Password: "password"
    Username: "username" Password: "p@££w0r46&"
    Username: "username" Password: "p@££w0r46&"
    

    【讨论】:

    • 我已经更新了我的答案,这个解决方案的问题是只包含 10k 行的文件需要大约 1.4 秒。
    • 不幸的是,在此之前清理数千个文件不适用于此任务。不过谢谢你的建议!
    猜你喜欢
    • 2015-08-22
    • 2014-06-17
    • 2013-01-20
    • 2015-06-11
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多