5

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

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

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

我目前正在使用 pattern ([A-Z0-9\s]+)\s*\:?\s*[\r\n](.+)[\r\n]{2},它可以正常工作(下面的解释),除非角色的语音中有换行符。发生这种情况时,角色的名字被成功捕获,但只捕获语音的第一行。

打开单行模式(包括换行符.)只会创建一个巨大的匹配。

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

理想情况下,我将能够匹配所有字符,直到整个模式被重复。


模式解释:

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

4

3 回答 3

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

于 2012-04-29T05:13:58.390 回答
0

好的,我做了一些修补,发现了一些有用的东西。它不是超级优雅,但它可以完成工作。

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

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

于 2012-04-29T04:02:50.630 回答
0

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

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

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

解释:

  • ((?:[A-Z]{2,}\s*:?\s*)+)- 第一组捕获人的大写名称 - 它将匹配“GREGOR”以及“MANFRED THE GREATEST:”
  • \s+- 至少一个空格字符
    然后至少重复一次:
  • (?![A-Z]{2,}\s*:?\s*)- 向前看以检查下一个文本是否不是大写字符名称
  • .+?[.?!]\s*- 匹配所有内容,直到找到一个结束句子的字符[.?!]和可选的空格
于 2012-04-29T16:43:03.320 回答