Получить данные между 1-м и 2-м каналами в python

Это мои выборочные данные

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

Я хочу получить результат как

 Indonesia 

В настоящее время я использую разделение на строку и доступ к значению. Но я хочу использовать регулярное выражение для него.

Некоторые условия, о которых нужно знать: данные могут быть пустыми. Данные не будут содержать трубку (|)

Я хочу использовать регулярное выражение вместо split, потому что я думаю, что regex более эффективен. Причина, по которой я хочу, чтобы это было как можно более эффективно, заключается в том, что исходный файл – 70 гб .

РЕДАКТИРОВАТЬ:

Это весь код, в котором я буду использовать этот

 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" 

То, что вызовет много накладных расходов, постоянно открывается и записывается, но если вы не сможете сохранить все строки в памяти, нет простого способа обойти его.

Что касается чтения, то в файле с десятью миллионами строк просто расщепление вдвое превосходит считыватель 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 

Вот выступление значимых ответов на Python 3.4.3:

 In [4]: timeit.timeit('s.split("|", 2)[1]', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"') Out[4]: 0.43930888699833304 In [10]: timeit.timeit('re.search(r"^[^a-zA-Z]*([a-zA-Z]+)", s).group(1)', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"; import re') Out[10]: 1.234878903022036 In [16]: timeit.timeit('re.search("^\d*\|(\w+?)?\|", s).group(1)', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"; import re') Out[16]: 1.8305770770530216 

Если нет труб:

 In [24]: timeit.timeit('s.split("|", 2)[1] if "|" in s else None', 's = "78|Indonesia|Pamela|Reid|preid25@gravatar.com|147.3.67.193"') Out[24]: 0.494665392965544 In [25]: timeit.timeit('s.split("|", 2)[1] if "|" in s else None', 's = ""') Out[25]: 0.04492994397878647 

Я думаю, вы можете найти свой ответ на: Python: Разделить строку по списку разделителей

 def split(txt, seps): default_sep = seps[0] # we skip seps[0] because that's the default seperator for sep in seps[1:]: txt = txt.replace(sep, default_sep) return [i.strip() for i in txt.split(default_sep)] 

Joschua (пользователь, который ответил на вопрос, связанный с выше) проверял, и это было более эффективно для регулярного выражения.

Просто возьмите первое слово, используя это регулярное выражение.

 re.search(r'^[^a-zA-Z]*([a-zA-Z]+)', S).group(1) 

это даст вам вещь между 1-й и 2-й трубами:

  re.search(r'(?<=\|)[^|]*',s).group() 

re.search (pattern, string, flags = 0) Сканировать строку, ища первое место, где шаблон регулярного выражения создает совпадение …..

Если всегда есть один и тот же канал труб, вы можете использовать регулярное выражение:

 [^|]+(?=(?:\|[^|]+\|?){4}$) 

DEMO

Это довольно просто: если вы знаете, что первое предложение всегда будет числом (или пустым), вы можете привязываться к фронту.

 ^\d*\|(\w+?)?\| 

Это будет соответствовать 0 или более номерам в передней части строки, а затем буквам | символ, за которым следует пункт 1, который будет содержать не-жадное совпадающее слово (без пробелов) или ничего, если оно не существует, за которым следует буквальный | персонаж.

Регулярное выражение производительности быстро выходит из строя, а негласные соответствия и привязки имеют решающее значение.