2013-09-02 34 views
5

Tôi đã đấu tranh với python regex trong một thời gian cố gắng để phù hợp với đoạn văn trong một văn bản, nhưng tôi đã không thành công. Tôi cần phải có được vị trí bắt đầu và kết thúc của các đoạn văn.Làm thế nào phù hợp với một đoạn bằng cách sử dụng regex

Một ví dụ về văn bản:

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 
vero eos et accusam et justo duo dolores et ea rebum. 

Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. 

Ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 
vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. 

Trong trường hợp ví dụ này, tôi muốn để phù hợp với độc lập toàn bộ các đoạn bắt đầu với Lorem, Stet và Ipsum tương ứng (không có dòng trống). Có ai có bất kỳ ý tưởng làm thế nào để làm điều này?

+1

Có một lý do tại sao bạn lại muốn làm điều này với regex? Đối với một cái gì đó đơn giản như tách các đoạn được giới hạn hai dòng mới, bạn chỉ có thể sử dụng 'paragraph.split ('\ n \ n')' –

+0

Tôi quan tâm đến vị trí bắt đầu và kết thúc của các đoạn văn, chứ không phải trong các chuỗi thực tế. Đáng lẽ tôi phải đề cập điều đó. –

Trả lời

3

Bạn có thể chia trên đúp xuống dòng như thế này:

paragraphs = re.split(r"\n\n", DATA) 

Edit: Để chụp các đoạn như phù hợp, vì vậy bạn có thể nhận được bắt đầu và ngày kết thúc điểm, làm điều này:

for match in re.finditer(r'(?s)((?:[^\n][\n]?)+)', DATA): 
    print match.start(), match.end() 

# Prints: 
# 0 214 
# 215 298 
# 299 589 
+0

Làm cách nào để sử dụng đối tượng đó? –

2

Sử dụng tính năng chia tách là một cách, bạn có thể làm như vậy với cụm từ thông dụng như sau:

paragraphs = re.search('(.+?\n\n|.+?$)',TEXT,re.DOTALL) 

Các .+? là một trận đấu lười biếng, nó sẽ phù hợp với chuỗi con ngắn nhất mà làm cho toàn bộ regex phù hợp. Nếu không, nó sẽ chỉ khớp với toàn bộ chuỗi.

Vì vậy, về cơ bản ở đây chúng tôi muốn tìm một chuỗi các ký tự (.+?) mà kết thúc bằng một dòng trống (\n\n) hoặc cuối chuỗi ($). Cờ re.DOTALL làm cho dấu chấm khớp với dòng mới (chúng tôi cũng muốn khớp một đoạn gồm ba dòng không có dòng trống bên trong)

+0

Cảm ơn câu trả lời của bạn. Tuy nhiên, lưu ý rằng mẫu này cũng khớp với các dòng trống, không đúng. –

0

Ký hiệu dòng mới là gì? Chúng ta hãy giả sử biểu tượng xuống dòng là '\ r \ n', nếu bạn muốn để phù hợp với đoạn bắt đầu với Lorem, bạn có thể làm như thế này:

pattern = re.compile('\r\nLorem.*\r\n') 
str = '...' # your source text 
matchlist = re.findall(pattern, str) 

Các matchlist sẽ chứa tất cả các paragragh bắt đầu với Lorem. Và hai từ còn lại là như nhau.

+0

Ký tự newline char trong python thường là \ n. Và mô hình của bạn không hoạt động. –

+0

Xin lỗi, tôi đã nhầm lẫn. Bạn có thể thử điều này: 'p = re.compile ('^ Lorem. * \ N') matchlist = re.findall (p, s)' Sau đó bạn sẽ nhận được danh sách các đoạn bắt đầu bằng Lorem –

0

Hãy thử

^(.+?)\n\s*\n 

hoặc

^(.+?)\r\n\s*\r\n 

chỉ đừng quên gắn thêm dòng mới vào cuối văn bản

0

tôi đã cố gắng để sử dụng RegEx khuyến cáo với công cụ Java RegEx mặc định . Điều đó đã cho tôi nhiều lần một StackOverflowException, vì vậy cuối cùng tôi viết lại RegEx và tối ưu hóa nó nhiều hơn một chút.

Vì vậy, đây là làm việc tốt cho tôi trong Java:

(?s)(.*?[^\:\-\,])(?:$|\n{2,}) 

này cũng xử lý cuối của tài liệu mà không cần dây chuyền mới và cố gắng để concat dòng mà kết thúc bằng ':', '-' hoặc '' đến đoạn tiếp theo.

Và để tránh điều đó trailing trống (khoảng trắng hoặc tab) phá vỡ tính năng mô tả ở trên tôi đang tước họ trước với regex sau:

(?m)[[:blank:]]+$ 
Các vấn đề liên quan