2013-02-26 3 views
0

Я использую findall для разделения текста.Регулярное выражение Python для r.findall

Я начал с этого выражения re.findall (r '(. ?) (\ $.? \ $)', Но он не дал мне данные после того, как найден последний фрагмент текста. «6 \ п \ п»

Как получить последний кусок текста

Вот мой питон код:

#!/usr/bin/env python 

import re 

allData = ''' 
1 
2 
3 here Some text in here 
$file1.txt$ 
4 Some text in here and more $file2.txt$ 
5 Some text $file3.txt$ here 
$file3.txt$ 
6 

''' 

for record in re.findall(r'(.*?)(\$.*?\$)|(.*?$)',allData,flags=re.DOTALL) : 
print repr(record) 

выход я получаю за это:

('\n1\n2\n3 here Some text in here \n', '$file1.txt$', '') 
('\n4 Some text in here and more ', '$file2.txt$', '') 
('\n5 Some text ', '$file3.txt$', '') 
(' here \n', '$file3.txt$', '') 
('', '', '\n6\n') 
('', '', '') 
('', '', '') 

Я действительно хотел бы этот выход:

('\n1\n2\n3 here Some text in here \n', '$file1.txt$') 
('\n4 Some text in here and more ', '$file2.txt$') 
('\n5 Some text ', '$file3.txt$') 
(' here \n', '$file3.txt$') 
('\n6\n', '',) 

Справочная информация в случае, если вам нужно, чтобы увидеть более широкую картину.

В случае, если вы заинтересованы, я переписываю это в python. Я контролирую остальную часть кода. Я просто получаю слишком много лишних вещей.

https://discussions.apple.com/message/21202021#21202021

+0

Что вы заменяете '$ file3.txt $' на? – Blender

+0

howabout просто используйте 'allData.strip()' –

+0

данные из файла. ie file3.txt – historystamp

ответ

2

Если я правильно понимаю, что от Apple, ссылку вы хотите сделать что-то вроде:

import re 


allData = ''' 
1 
2 
3 here Some text in here 
$file1.txt$ 
4 Some text in here and more $file2.txt$ 
5 Some text $file3.txt$ here 
$file3.txt$ 
6 

''' 


def read_file(m): 
    return open(m.group(1)).read() 

# Sloppy matching :D 
# print re.sub("\$(.*?)\$", read_file, allData) 
# More precise. 
print re.sub("\$(file\d+?\.txt)\$", read_file, allData) 

EDIT Как Оскар предлагает сделать матч более точным.

ie. возьмите имя файла между $ и прочитайте файл для данных, и это будет сделано выше.

Пример вывода:

1 
2 
3 here Some text in here 

I'am file1.txt 

4 Some text in here and more 
I'am file2.txt 

5 Some text 
I'am file3.txt 
here 

I'am file3.txt 

6 

Файлы:

==> file1.txt <== 

I'am file1.txt 

==> file2.txt <== 

I'am file2.txt 

==> file3.txt <== 

I'am file3.txt 
+1

+1. Я не знаю, могут ли быть другие символы '' 'в тексте, но если это так, вы можете ограничить его' \ $ (. *? \. Txt) \ $ 'или даже' \ $ (файл \ d +? \. txt) \ $ ' –

+0

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

+0

Да, непревзойденный $ может быть проблемой, но решения bash & perl, похоже, не заботятся об этом. – historystamp

0

Это один частично решить проблему

import re 

allData = ''' 
1 
2 
3 here Some text in here 
$file1.txt$ 
4 Some text in here and more $file2.txt$ 
5 Some text $file3.txt$ here 
$file3.txt$ 
6 

''' 

for record in re.findall(r'(.*?)(\$.*?\$)|(.*?$)',allData.strip(),flags=re.DOTALL) : 
    print [ x for x in record if x] 

продуцирующие выход

['1\n2\n3 here Some text in here \n', '$file1.txt$'] 
['\n4 Some text in here and more ', '$file2.txt$'] 
['\n5 Some text ', '$file3.txt$'] 
[' here \n', '$file3.txt$'] 
['\n6'] 
[] 

Избегайте последний пустой список с

for record in re.findall(r'(.*?)(\$.*?\$)|(.*?$)',allData.strip(),flags=re.DOTALL) : 
    if ([ x for x in record if x] != []): 
     print [ x for x in record if x] 
1

Для достижения выхода вы хотите вам необходимо ограничить ваш шаблон на 2 группы захвата. (Если вы используете 3 группы захвата, у вас будет 3 элемента в каждой «записи»).

Вы могли бы сделать вторую группу необязательно, что должен делать эту работу:

r'([^$]*)(\$.*?\$)?' 
1

Вот один из способов решить проблему замещения с findall.

def readfile(name): 
    with open(name) as f: 
     return f.read() 

r = re.compile(r"\$(.+?)\$|(\$|[^$]+)") 

print "".join(readfile(filename) if filename else text 
    for filename, text in r.findall(allData)) 
Смежные вопросы