我读过很多关于StackOverflow的问题,包括这个,这个,甚至读过Rexegg's Best Trick,这也是一个问题。我找到了这个,它适用于整行,但不是"一切都到了坏词"。这些都没有帮助我,所以我来了:
在Javascript中,我有一个很长的正则表达式模式。我正在尝试匹配类似句子结构中的序列,如下所示:
1 唯一前缀 [some-token] 和 [some-token] 想拿 [some-token] 去看一些猴子。
2 UniqueC [some-token] 想要将 [some-token] 带到商店。UniqueB,[某种令牌]再次出现在模式中。
3 唯一前缀 [some-token] 正在使用 [some-token] 到 [some-token]。
请注意,每个模式都以唯一的前缀开头。遇到该前缀表示模式的开始。如果我在捕获过程中再次遇到该模式,我不应该捕获第二次出现,并停止在那里。我将捕获该前缀之前的所有内容。
如果我在模式的后面没有遇到前缀,我需要继续匹配该模式。
我还使用捕获组(不重复,因为捕获组仅返回该组的最后一个匹配项)。捕获组内容需要返回,所以我使用匹配,非贪婪。
这是我的模式和一个工作示例
/(?:UniquePrefixA|UniqueB|UniqueC)s*([some-token])(?:and|s)*([some-token])?(s|[^[]])*([some-token])? --->(s|[^[]])*<--- ([some-token])?(s|[^[]])*/i
它基本上是按特定顺序排列的 2 个重复模式:
(s|[^[]])* // Basicaly .*, but excluding brackets
([some-token]) // A token [some-token]
如何防止匹配继续超过黑名单?
我希望这发生在我画了三个箭头的地方,作为上下文。等效的 Any 字符,但不是此列表的内容:(唯一前缀 A|独一无二|唯一 C)(如捕获组 1 所示)。
我可能需要更好地了解负面的展望,或者它是否可以处理一组事情。最重要的是,我想知道消极的前瞻性方法是否可以支持一系列选项。还是有更好的方法?如果答案是"你不能那样做",那也很酷。
我认为,一个更容易维护的解决方案是将你的任务分为两部分:
查找从任何唯一前缀开始的每个文本块, 直到字符串的下一个或结尾。
处理每个这样的块,寻找你的一些令牌,也许 还有它们之间的内容。
执行第一个任务的正则表达式应包括 3 个部分:
(?:UniquePrefixA|UniqueB|UniqueC)
- 一个非捕获组看起来 对于任何唯一前缀。((?:.|n)+?)
- 捕获组 - 要进一步捕获的片段 处理(请参阅下面的注释)。(?=UniquePrefixA|UniqueB|UniqueC|$)
- 积极的展望,展望 对于任何唯一前缀或字符串的结尾(您要查找的停止条件)。
总而言之,整个正则表达式如下所示:
/(?:UniquePrefixA|UniqueB|UniqueC)((?:.|n)+?)(?=UniquePrefixA|UniqueB|UniqueC|$)/gi
注意:不幸的是,正则表达式的JavaScript风格没有实现单行(-s) 选项。因此,而不仅仅是在捕获组中.
上面,你必须使用(?:.|n)
,意思是:
- 除
n
(.
)以外的任何字符, - 或者只是
n
.
这两种变体都被"包裹"成一个非捕获组, 要限制变体(|
的两面),因为重复 标记(+?
)与这两个变体有关。
注意?
在+
之后,意思是不情愿的版本。
所以正则表达式的这一部分(捕获组)将匹配任何字符序列包括n
,在下一个 uniqie 前缀(如果有)之前结束, 正如你所料。
第二个任务是将另一个正则表达式应用于捕获的块(组 1), 查找[some-token]
以及它们之间的可能内容。 您没有指定要对每个块执行的确切操作, 所以我不确定第二个正则表达式应该包括什么。 也许仅仅匹配[some-token]
就足够了?
为了确保模式不会出现在重复字符序列中,例如(s|[^[]])*
,请注意s
包含在[^[]]
中,因此可能只是[^[]]*
,是在重复模式的左侧和内部加上一个否定的展望(这是一个像^
这样的零匹配断言),以便检查每个字符:
((?!UniquePrefixA)(s|[^[]]))*