正则表达式匹配所有字符直到下一个匹配

时间:2012-04-29 02:57:55

标签: javascript regex parsing

我正在解析多次重复简单模式的文本。文本采用剧本脚本的格式,如下所示:

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},它工作正常(下面的说明),除非角色的语音中有换行符。当发生这种情况时,成功捕获角色的名称,但只捕获语音的第一行。

启用单线模式(包括.中的换行符)只会创建一个巨大的匹配。

(.+)找到下一个字符名称并结束匹配时,如何告诉{{1}}停止? 我正在单独迭代每个匹配(JavaScript),因此该名称必须可用于下一场比赛。

理想情况下,我可以匹配所有字符,直到重复整个模式。


模式解释:

第一组匹配一个角色的名字(允许大写字母,数字和空格),(尾部冒号和空格可选)。
第二组(角色的演讲)从一个新行开始并捕获任何字符(除了有问题的,换行符和后面的字符)。
模式在空行后结束(并重新开始)。

3 个答案:

答案 0 :(得分:1)

考虑采用不同的方向。您真的想在包含名称的任何行上拆分更大的对话框。您可以使用正则表达式执行此操作(将正则表达式替换为与“speaker”行匹配的任何内容):

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来获取跨平台行为。

答案 1 :(得分:0)

好的,我做了一点修修补补,找到了有效的方法。它不是超级优雅,但它确实起到了作用。

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

我修改了最后一个捕获组,允许无限重复任意文本,新行和更多任意文本。由于不允许连续两行换行,因此模式在演讲结束后结束。

答案 2 :(得分:0)

我终于设法让它只匹配你想要的东西,即
- 角色的名称,允许空格和冒号 - 以及可选的多行与换行符,与该人相关联的文本

您需要使用此正则表达式findAll - 它区分大小写:

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

说明:

  • ((?:[A-Z]{2,}\s*:?\s*)+) - 第一组捕获此人的大写名称 - 它将匹配“GREGOR'以及“最棒的人”:'
  • \s+ - 至少有一个空格字符
    然后至少重复一次:
  • (?![A-Z]{2,}\s*:?\s*) - 向前看以确认下一个文字不是大写字母名称
  • .+?[.?!]\s* - 匹配所有内容,直到找到结束句子[.?!]并且可选地为空格的字符