2008-09-22 17 views
5

Làm cách nào để viết biểu thức chính quy để sử dụng trong python để chia đoạn văn?biểu thức chính quy python để chia đoạn văn

Đoạn được xác định bằng 2 ngắt dòng (\ n). Nhưng người ta có thể có bất kỳ số lượng không gian/tab cùng với các ngắt dòng, và nó vẫn nên được coi là một đoạn văn.

Tôi đang sử dụng python để giải pháp có thể sử dụng python's regular expression syntax được mở rộng. (Có thể tận dụng (?P...) thứ)

Ví dụ:

the_str = 'paragraph1\n\nparagraph2' 
# splitting should yield ['paragraph1', 'paragraph2'] 

the_str = 'p1\n\t\np2\t\n\tstill p2\t \n  \n\tp3' 
# should yield ['p1', 'p2\t\n\tstill p2', 'p3'] 

the_str = 'p1\n\n\n\tp2' 
# should yield ['p1', '\n\tp2'] 

Điều tốt nhất tôi có thể đến với là: r'[ \t\r\f\v]*\n[ \t\r\f\v]*\n[ \t\r\f\v]*', ví dụ:

import re 
paragraphs = re.split(r'[ \t\r\f\v]*\n[ \t\r\f\v]*\n[ \t\r\f\v]*', the_str) 

nhưng đó là xấu xí. Có gì tốt hơn không?

EDIT:

Gợi ý từ chối:

r'\s*?\n\s*?\n\s*?' -> Điều đó sẽ làm ví dụ 2 và 3 thất bại, kể từ \s bao gồm \n, vì vậy nó sẽ cho phép định dạng các đoạn với hơn 2 \n s.

Trả lời

4

Thật không may là không có cách nào tốt đẹp để viết "không gian nhưng không phải là một dòng mới".

Tôi nghĩ rằng tốt nhất bạn có thể làm là thêm một số không gian với modifier x và cố gắng yếu tố ra sự xấu xí một chút, nhưng đó là vấn đề: (?x) (?: [ \t\r\f\v]*? \n){2} [ \t\r\f\v]*?

Bạn cũng có thể thử tạo một subrule chỉ dành riêng cho các lớp nhân vật và nội suy nó ba lần.

+2

Có. [^ \ S \ n] :) –

0

Hầu như giống nhau, nhưng sử dụng các định lượng không tham lam và tận dụng chuỗi khoảng trắng.

\s*?\n\s*?\n\s*? 
+0

làm ví dụ 2 không thành công, vì \ s bao gồm \ n. – nosklo

2

Bạn đang cố gắng suy ra cấu trúc của tài liệu trong thử nghiệm đơn giản? Bạn có đang làm gì docutils không?

Bạn có thể chỉ cần sử dụng Docutils parser thay vì cuộn của riêng bạn.

1

Không phải là một regexp nhưng thực sự tao nhã:

from itertools import groupby 

def paragraph(lines) : 
    for group_separator, line_iteration in groupby(lines.splitlines(True), key = str.isspace) : 
     if not group_separator : 
      yield ''.join(line_iteration) 

for p in paragraph('p1\n\t\np2\t\n\tstill p2\t \n  \n\tp'): 
    print repr(p) 

'p1\n' 
'p2\t\n\tstill p2\t \n' 
'\tp3' 

Đó là tùy thuộc vào bạn để dải đầu ra khi bạn cần nó tất nhiên.

Lấy cảm hứng từ "Sách nấu ăn Python" nổi tiếng ;-)

+0

Giải pháp gọn gàng. 'Str_isspace' là gì? –

+0

Một lỗi đánh máy :-) Bạn nên đọc str.isspace một phương thức isspace() từ chuỗi đối tượng. Nó sẽ được gọi để xác định xem một cái gì đó là một không gian, và sẽ nhóm đối tượng theo đó. Tôi sửa nó rồi. –

+0

Tuyệt vời, điều đó có ý nghĩa - cảm ơn :) –