2012-04-29 170 views
5

我正在解析許多重複的簡單模式的文本。該文本是在腳本中的一個播放的格式,如:正則表達式匹配所有字符直到下一個匹配

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

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

我目前使用的模式([A-Z0-9\s]+)\s*\:?\s*[\r\n](.+)[\r\n]{2},工作正常(下文解釋),除了在人物的講話中有換行符。當發生這種情況時,角色的名字被成功捕獲,但只有語音的第一行被捕獲。

打開單行模式(包括.中的換行符)只是創建一個巨大的匹配。

如何在(.+)找到下一個字符名稱並結束匹配時停止?
我正在遍歷每個匹配(JavaScript),所以名稱必須可用於下一場比賽。

理想情況下,我將能夠匹配所有字符,直到整個模式重複。


模式解釋說:

第一組相匹配的角色的名字(允許大寫字母,數字和空格),(後面有個冒號和空格可選)。
第二組(角色的演講)從新行開始並捕獲任何字符(除了問題,換行符和後面的字符)。
模式在空行後結束(並重新開始)。

+0

您需要明確地定義如何一個決定下一個名字開始之前,你可以令狀e正則表達式來匹配它。它本身是否有冒號的單個單詞?會導致任何不正確的匹配? – mellamokb 2012-04-29 03:25:09

+0

@mellamokb我忘了包括模式的最後一部分,它尋找一個空行。比賽以角色的名字開始(全部大寫在自己的行上),並以演講結束後的空白行結束。 – Nathan 2012-04-29 03:33:45

+0

我相信你在示例文本中缺少冒號,正則表達式不適用於它。 – 2012-04-29 03:39:36

回答

0

好的,我做了一些修補,發現了一些可行的方法。它不是超級優雅,但它的工作。

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

我修改了最後一個捕獲組,允許任意文本,新行和更多任意文本的無限重複。由於不允許連續兩個換行符,因此該模式在發言後結束。

+0

我只是想指出,我把你的問題的正則表達式和例子粘貼到[正則表達式測試工具](http://gskinner.com/RegExr/)中,然後只需啓用* dotall *模式(點匹配換行符)你的問題。奇怪的是,沒有爲你工作 – Hubro 2012-04-29 04:05:59

1

考慮與此不同的方向。您真的想在包含名稱的任何行上分割更大的對話。您可以使用正則表達式做到這一點還是(替換任何匹配的「揚聲器」行正則表達式):兼容的實現,你比如文本將在這樣一個數組結束

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

在一個標準:

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. " 

一個告誡是,大多數瀏覽器在這裏的標準參差不齊。您可以使用庫XRegExp獲取跨平臺行爲。

+0

在我的使用情況下,將對話分成不同的行是沒有意義的。由於程序(和用戶)作爲一個整體與對話進行交互,我只需要將它們再次拼接在一起,這樣它們就會有用。 – Nathan 2012-04-29 05:37:20

0

我終於設法讓它匹配你想要的東西,即
- 字符的名稱,允許空格和冒號
- 和,任選換行符多,與人相關的文本

您需要使用此正則表達式做findAll - 它是區分大小寫:

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

說明:

  • ((?:[A-Z]{2,}\s*:?\s*)+) - 第一組捕獲的人的大寫的名字 - 它將匹配「GREGOR」以及「曼弗雷德THE GREATEST:」
  • \s+ - 至少一個空白字符
    然後至少重複一次:
  • (?![A-Z]{2,}\s*:?\s*) - 前瞻檢查接下來的文字是不是上字母字符名稱
  • .+?[.?!]\s* - 直到找到結束一個句子一個字符匹配一切[.?!]和可選的空格