2012-04-29 172 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* - 直到找到结束一个句子一个字符匹配一切[.?!]和可选的空格