2015-12-18 3 views
0

У меня есть список todo.txt, как это, разделенных символами новой строки:Получить текст, окружающий регулярок матч с питоном

(D) 2015-02-18 XDA Ultimate guide to +Tasker @Phone @Computer 
2015-02-18 Redesign the business card for +RepairWork @Computer 
(A) 2015-02-17 +Study how to +Ask questions @Computer @Phone 
(B) 2015-03-25 Update +LaundryTimer W/ new popup design +Tasker 

И у меня есть регулярное выражение для захвата + Проекты и @Contexts:

## Projects 
project_matches = re.findall('[+]\D\w+',todo_list) 
print list(set(project_matches)) 

## Contexts 
context_matches = re.findall('[@][A-Z]\w+',todo_list) 
print list(set(context_matches)) 

Но я также хотел бы быстро и эффективно захватить каждую задачу и группу с помощью + Project или @Context.

Например, здесь есть искомый результат:

Phone: 

(A) 2015-02-17 +Study how to +Ask questions @Computer @Phone 
(D) 2015-02-18 XDA Ultimate guide to +Tasker @Phone @Computer 

Computer: 

(D) 2015-02-18 XDA Ultimate guide to +Tasker @Phone @Computer 
2015-02-18 Redesign the business card for +RepairWork @Computer 

Tasker: 

(D) 2015-02-18 XDA Ultimate guide to +Tasker @Phone @Computer 
(B) 2015-03-25 Update +LaundryTimer W/ new popup design +Tasker 

Etc ...

У меня также есть Regex захватить задачу, когда он находит проект или контекст, но я не знать, если это помогает: (.*)(?=[+]\D\w+)(.*)

ответ

2

Вы можете создать несколько словарей. defaultdict упрощает запуск каждого элемента с list.

import collections 
projects = collections.defaultdict(list) 
contexts = collections.defaultdict(list) 
with open('todo_list.txt') as todo_list: 
    for line in todo_list: 
     for item in re.findall(r'[+]\D\w+', line): 
      projects[item].append(line) 
     for item in re.findall(r'[@][A-Z]\w+', line): 
      contexts[item].append(line) 

Если вы уже прочитали весь файл в одну строку, используйте splitlines() перебирать каждую строку:

import collections 
projects = collections.defaultdict(list) 
contexts = collections.defaultdict(list) 
for line in todo_list.splitlines(): 
    for item in re.findall(r'[+]\D\w+', line): 
     projects[item].append(line) 
    for item in re.findall(r'[@][A-Z]\w+', line): 
     contexts[item].append(line) 
0

Вы можете захватить всю линию, где данное слово происходит с помощью ^.*word.*$

Значения: с самого начала строки ^ соответствует любому символу . любое количество раз *, затем сопоставить слово. не соответствует любому символу, несколько раз снова .* до конца строки $

Чтобы выполнить свою задачу, вы могли бы сделать что-то вроде

tasks = re.findall(r"(^.*?%s.*?$)" % context, todo_list, re.MULTILINE) 

где context это слово вы ищете (телефон, компьютер, Tasker и т. д.)

Редактировать: re.MULTILINE делает re совпадений в каждой строке. Он действует как модификатор g. Вы можете увидеть мой пример в действии здесь: https://regex101.com/r/gS2yN9/1