我正在解析多次重复简单模式的文本。文本采用剧本脚本的格式,如下所示:
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),因此该名称必须可用于下一场比赛。
理想情况下,我可以匹配所有字符,直到重复整个模式。
模式解释:
第一组匹配一个角色的名字(允许大写字母,数字和空格),(尾部冒号和空格可选)。
第二组(角色的演讲)从一个新行开始并捕获任何字符(除了有问题的,换行符和后面的字符)。
模式在空行后结束(并重新开始)。
答案 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*
- 匹配所有内容,直到找到结束句子[.?!]
并且可选地为空格的字符