这是我的样本数据

78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193

我想得到结果
Indonesia

目前,我正在字符串上使用split并访问该值但我想用正则表达式。
需要注意的一些条件:
数据可能为空
数据不包含管道()
我想使用regex而不是split,因为我认为regex更有效。我希望尽可能高效的原因是源文件是70GB。
编辑:
这是我要使用的全部代码
def main(argv):
    mylist = set();
    input_file = open("test.txt", 'r')

    for row in input_file:
        rowsplit = row.split("|");

        if rowsplit[1] !='':
            if rowsplit[1] in mylist:
                filename= "bby_"+rowsplit[1]+".dat";
                existingFile=open(filename,'a')
                existingFile.write(row);
                existingFile.close()
            else:
                mylist.add(rowsplit[1])
                filename= "bby_"+rowsplit[1]+".dat";
                newFile = open(filename,'a')
                newFile.write(row);
                newFile.close();
        else:
            print "Empty"
    print mylist

我只是不知道现在该用哪一个答案:(
我只想让这段代码快一点。就这样。

最佳答案

拆分和检查长度可能仍然比正则表达式快:

for line in f:
    spl = line.split("|",2)
    if len(spl) > 2:
        print(spl[1])
       ....

匹配和非匹配行上的一些计时:
In [24]: s = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"

In [25]: %%timeit
    spl = s.split("|",2)
    if len(spl) > 2:
        pass
   ....:
1000000 loops, best of 3: 413 ns per loop

In [26]: r = re.compile(r'(?<=\|)[^|]*')

In [27]: timeit r.search(s)
1000000 loops, best of 3: 452 ns per loop

In [28]: s = "78 Indonesia Pamela Reid preid25@gravatar.com 147.3.67.193"

In [29]: timeit r.search(s)
1000000 loops, best of 3: 1.66 µs per loop

In [30]: %%timeit
    spl = s.split("|",2)
    if len(spl) > 2:
        pass
   ....:
1000000 loops, best of 3: 342 ns per loop

通过创建str.split的本地引用,您可以省去一些麻烦:
_spl = str.split
for line in f:
    spl = _spl(s,"|",2)
    if len(spl) > 2:
      .....

因为每行中的管道数量总是相同的:
def main(argv):
    seen = set() # only use if you actually need  a set of all names
    with open("test.txt", 'r') as infile:
        r = csv.reader(infile, delimiter="|")
        for row in r:
            v = row[1]
            if v:
                filename = "bby_" + v + ".dat"
                existingFile = open(filename, 'a')
                existingFile.write(row)
                existingFile.close()
                seen.add(v)
            else:
                print "Empty"

如果/else在附加到文件时显得多余,不管怎样,如果出于另一个原因希望保留行[1]的集合,则每次都可以添加到该集合,除非实际上需要一组所有名称,否则我会将其从代码中删除。
对拆分应用相同的逻辑:
def main(argv):
    seen = set()
    with open("test.txt", 'r') as infile:
        _spl = str.split
        for row in infile:
            v = _spl(row,"|",2)[1]
            if v:
                filename = "bby_" + v + ".dat"
                existingFile = open(filename, 'a')
                existingFile.write(row)
                existingFile.close()
                seen.add(v)
            else:
                print "Empty"

会导致大量开销的是不断的打开和写入,但是除非你能将所有的行存储在内存中,否则没有简单的方法可以绕过它。
就阅读而言,在一个1000万行的文件上,只需拆分两倍就可以超过csv阅读器:
In [15]: with open("in.txt") as f:
   ....:     print(sum(1 for _ in f))
   ....:
10000000

In [16]: paste
def main(argv):
    with open(argv, 'r') as infile:
        for row in infile:
            v = row.split("|", 2)[1]
            if v:
                pass
## -- End pasted text --

In [17]: paste
def main_r(argv):
    with open(argv, 'r') as infile:
        r = csv.reader(infile, delimiter="|")
        for row in r:
            if row[1]:
                pass

## -- End pasted text --

In [18]: timeit main("in.txt")
1 loops, best of 3: 3.85 s per loop

In [19]: timeit main_r("in.txt")
1 loops, best of 3: 6.62 s per loop

09-11 17:21
查看更多