2012-04-29 35 views
5

Tôi đang phân tích văn bản có nhiều lần lặp lại của một mẫu đơn giản. Các văn bản có định dạng của một kịch bản cho một vở kịch, như thế này:Cụm từ thông dụng để khớp tất cả các ký tự cho đến kết quả tiếp theo

SAMPSON 
I mean, an we be in choler, we'll draw. 

GREGORY 
Ay, while you live, draw your neck out o' the collar. 

Tôi hiện đang sử dụng mô hình ([A-Z0-9\s]+)\s*\:?\s*[\r\n](.+)[\r\n]{2}, mà hoạt động tốt (giải thích dưới đây) trừ khi bài phát biểu của nhân vật có ngắt dòng trong đó . Khi điều đó xảy ra, tên của nhân vật được chụp thành công nhưng chỉ có dòng đầu tiên của bài phát biểu được chụp.

Bật chế độ một đường (để bao gồm ngắt dòng trong .) chỉ cần tạo một kết hợp khổng lồ.

Làm thế nào tôi có thể yêu cầu số (.+) dừng lại khi tìm thấy tên ký tự tiếp theo và kết thúc trận đấu?
Tôi đang lặp qua từng kết hợp riêng lẻ (JavaScript), vì vậy tên phải có sẵn cho kết quả phù hợp tiếp theo.

Lý tưởng nhất, tôi có thể khớp tất cả các ký tự cho đến khi lặp lại toàn bộ mẫu.


mẫu giải thích:

Nhóm đầu tiên phù hợp với tên của một nhân vật (cho phép chữ in hoa, chữ số, và khoảng trắng), (với một dấu hai chấm trailing và khoảng trắng không bắt buộc).
Nhóm thứ hai (lời nói của nhân vật) bắt đầu trên một dòng mới và ghi lại bất kỳ ký tự nào (ngoại trừ, có sự cố, ngắt dòng và ký tự sau chúng).
Mẫu kết thúc (và bắt đầu lại) sau một dòng trống.

+0

bạn cần phải rõ ràng xác định cách một xác định nơi tên tiếp theo bắt đầu trước khi bạn có thể lệnh e một regex để phù hợp với nó. Có bất kỳ từ đơn nào theo sau là dấu hai chấm trên một dòng không? Điều đó có dẫn đến kết quả trùng khớp không chính xác không? – mellamokb

+0

@mellamokb Tôi quên bao gồm phần cuối của mẫu, tìm kiếm một dòng trống. Trận đấu bắt đầu tại tên của nhân vật (tất cả các mũ trên dòng riêng của nó) và kết thúc ở dòng trống sau bài phát biểu. – Nathan

+0

Tôi tin rằng bạn đang thiếu dấu hai chấm trong văn bản mẫu của bạn, regex không hoạt động với nó. –

Trả lời

0

Được rồi, tôi đã làm một chút tinkering và tìm thấy một cái gì đó hoạt động. Nó không phải là siêu thanh lịch, nhưng nó thực hiện công việc.

([A-Z0-9\s]+)\s*\:?\s*[\r\n]((.+[\r\n]?.*)+)[\r\n]{2} 

Tôi đã sửa đổi nhóm chụp cuối cùng để cho phép lặp lại vô tận văn bản tùy ý, dòng mới và văn bản tùy ý hơn. Vì hai ngắt dòng trong một hàng không được phép, mẫu sẽ kết thúc sau lời nói.

+0

Tôi chỉ muốn chỉ ra, tôi dán regex và ví dụ từ câu hỏi của bạn vào [một công cụ kiểm tra regex] (http://gskinner.com/RegExr/) sau đó chỉ cần kích hoạt chế độ * dotall * (dấu chấm phù hợp với dòng mới) được giải quyết vấn đề của bạn. Thật lạ lùng khi không hoạt động với bạn – Hubro

1

Cân nhắc đi theo một hướng khác với điều này. Bạn thực sự muốn tách một cuộc đối thoại lớn hơn trên bất kỳ dòng nào có chứa tên. Bạn có thể làm điều này với một biểu thức chính quy vẫn (thay thế regex với bất cứ điều gì sẽ phù hợp với "loa" dòng):

results = "Insert script here".split(/^([A-Z]+)$/) 

Trên một tiêu chuẩn thực hiện phù hợp, bạn ví dụ văn bản sẽ kết thúc trong một mảng như sau:

results[0] = "" 
results[1] = "SAMPSON"  
results[2] = "I mean, an we be in choler, we'll draw.    
" 
results[3] = "GREGORY"  
results[4] = "Ay, while you live, draw your neck out o' the collar. " 

Lưu ý rằng hầu hết các trình duyệt đều có tiêu chuẩn ở đây. Bạn có thể sử dụng thư viện XRegExp để nhận hành vi nền tảng chéo.

+0

Trong trường hợp sử dụng của tôi, việc chia hộp thoại thành các dòng riêng biệt không có ý nghĩa. Vì chương trình (và người dùng) tương tác với các hộp thoại như một tổng thể, tôi sẽ chỉ cần ghép chúng lại với nhau để chúng có ích. – Nathan

0

Cuối cùng tôi đã xoay xở để làm cho nó chỉ khớp với những gì bạn muốn, tức là
- tên của nhân vật, cho phép khoảng trắng và ruột kết
- và, tùy chọn Multiline với linebreaks, các văn bản liên quan đến người

Bạn sẽ cần phải làm findAll sử dụng regex này - đó là trường hợp nhạy cảm:

((?:[A-Z]{2,}\s*:?\s*)+)\s+((?![A-Z]{2,}\s*:?\s*).+?[.?!]\s*)+ 

Giải thích:

  • ((?:[A-Z]{2,}\s*:?\s*)+) - nhóm đầu tiên nắm bắt được tên chữ hoa của con người - đó sẽ phù hợp 'Gregor' cũng như 'Manfred The Greatest:'
  • \s+ - ít nhất một ký tự khoảng trắng
    Sau đó lặp lại ít nhất một lần:
  • (?![A-Z]{2,}\s*:?\s*) - nhìn về phía trước để kiểm tra xem các văn bản bên cạnh không phải là thượng trường hợp tên nhân vật
  • .+?[.?!]\s* - phù hợp với tất cả mọi thứ cho đến khi bạn tìm thấy một nhân vật mà kết thúc một câu [.?!] và tùy chọn khoảng trắng
Các vấn đề liên quan