用于分隔文本的前瞻

时间:2016-06-13 19:26:06

标签: javascript regex

我正试图用里面的几个文件分隔一个巨大的文本。每个文件都以“MINISTÉRIO”开头,所以我试图使用前瞻来捕捉从MINISTÉRIO到下一个MINISTÉRIO的所有内容:

(MINISTÉRIO)[\s\S]*?(^(?=\1))

http://regexr.com/3dk6k

我也试图:

(^MINISTÉRIO)[\s\S]*?(?=\1)

http://regexr.com/3dk6h

虚空正在工作。我有两个问题:为什么我的正则表达式不起作用?应该是我想...而且,如何解决?

谢谢!

1 个答案:

答案 0 :(得分:0)

问题描述

/(MINISTÉRIO)[\s\S]*?(^(?=\1))/gm匹配文字中任意位置的单词MINISTÉRIO ,将其捕获到群组1中。[\s\S]*?懒惰地匹配任何字符,0或更多重复直到一行后面跟着单词MINISTÉRIO。因此,如果您从字符串中的某个位置到结尾有“文档”,则无法找到该匹配项,因为您无法指定$锚点,因为它已重新定义以匹配结尾

使用/(^MINISTÉRIO)[\s\S]*?(?=\1)/g,您只匹配并捕获整个字符串开头的MINISTÉRIO字,并尽可能少地匹配任何字符,直到第一个MINISTÉRIO子字符串为止。 string,在字符串中的任何位置,并且不检查行的开头。

解决方案

您可以使用展开的正则表达式

/^MINISTÉRIO\b.*(?:\n(?!MINISTÉRIO\b).*)*/gm

regex demo is here

当文本太长时,像模式中的延迟匹配需要花费太多时间,使用否定字符类可以大大提高性能。

简而言之:

  • ^MINISTÉRIO\b - 在一行开头将MINISTÉRIO作为整个单词匹配:
    • ^ - 一行开始(由于/m修饰符)
    • MINISTÉRIO\b - 整个单词MINISTÉRIO\b是单词边界
  • .*(?:\n(?!MINISTÉRIO\b).*)* - 匹配行开头不是MINISTÉRIO的任何文字:
    • .* - 除了换行符之外的0 +字符
    • (?:\n(?!MINISTÉRIO\b).*)* - 0+序列:
    • \n(?!MINISTÉRIO\b) - 未跟随MINISTÉRIO作为整个单词的换行符
    • .* - 除了换行符之外的0 +字符

它基本上与/^MINISTÉRIO\b(?:(?!^MINISTÉRIO\b)[\s\S])*/gm相同,但应该更快,因为冥想贪婪令牌(?:(?!^MINISTÉRIO\b)[\s\S])*)相当耗费资源。