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

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),所以下一个匹配需要知道名称。

理想情况下,我希望能够匹配所有人物,直到整个模式重复。


模式说明:

第一组匹配人物名称(允许大写字母、数字和空格),(尾随冒号和空格可选)。
第二组(人物的对话)从新行开始捕获任何字符(除了问题是换行符和其后面的字符)。
模式在空行后结束(并重新开始)。


在编写正则表达式之前,您需要明确定义下一个名称的起始位置是如何确定的。它是指在单独一行上的任何单词后面跟着冒号吗?这样会导致任何错误的匹配吗? - mellamokb
@mellamokb 我忘记包含模式的最后一部分,它用于查找空行。匹配从字符名(大写字母单独一行)开始,到发言后的空行结束。 - Nathan
我认为你的示例文本中缺少冒号,正则表达式无法使用。 - Theron Luhn
@TheronLuhn 冒号应该是可选的;如果缺失,正则表达式仍然应该工作。换行符是重要的部分。 - Nathan
无论它应该做什么,你的示例与你的正则表达式不兼容,这对我们来说没有太大帮助。除了冒号之外,你的正则表达式似乎还需要在结尾处添加两个换行符,这也没有在示例中体现出来。 - Theron Luhn
@TheronLuhn 啊,是多余的新行。我已经添加了我可以添加的,但最后一个被切掉了。对此很抱歉! - Nathan
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来获得跨平台行为。


在我的使用情况中,将对话框分成单独的行没有意义。由于程序(和用户)与对话框作为一个整体进行交互,我只需要将它们拼接在一起,这样它们才有用。 - Nathan

0

好的,我进行了一些调整并找到了可行的解决方案。虽然不是非常优雅,但它能够完成任务。

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

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


我只是想指出,我将你的问题中的正则表达式和示例粘贴到了一个正则表达式测试工具中,然后简单地启用了dotall模式(点匹配换行符),这解决了你的问题。奇怪的是,这对你来说没有起作用。 - Hubro

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* - 匹配直到找到结束句子的字符[.?!] 以及可选空格的所有内容

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接