Javascript - 正则表达式 - 将多个单词的黑名单添加到END并进行部分匹配

时间:2018-01-04 05:37:31

标签: javascript regex blacklist

我已经阅读了很多关于StackOverflow的问题,包括this onethis one,甚至是Rexegg's Best Trick,这也是问题here。我找到this one,它适用于整行,但不是“一切都是坏词”。这些都没有帮助我,所以我走了:

Javascript 中,我有一个很长的正则表达式模式。我正在尝试匹配类似句子结构中的序列,如下所示:

  

1 UniquePrefixA [some-token]和[some-token]想要[some-token]看一些猴子。

     

2 UniqueC [some-token]希望将[some-token]带到商店。 UniqueB,[some-token]再次出现在模式中。

     

3 UniquePrefixA [some-token]正在使用[some-token]来[some-token]。

请注意,每个模式都以唯一的前缀开头。遇到该前缀表示模式的开始。 如果我在捕获期间再次遇到该模式,我不应该捕获第二次出现,并且停止那里。我将捕获到该前缀的所有内容。

如果我在模式中稍后没有遇到前缀,我需要继续匹配该模式。

我也在使用捕获组(不重复,因为捕获组仅返回该组的最后一个匹配)。需要返回捕获组内容,因此我使用匹配,非贪婪。

这是我的模式和working example

/(?:UniquePrefixA|UniqueB|UniqueC)\s*(\[some-token\])(?:and|\s)*(\[some-token\])?(\s|[^\[\]])*(\[some-token\])? --->(\s|[^\[\]])*<--- (\[some-token\])?(\s|[^\[\]])*/i

它基本上是按特定顺序重复的两种模式:

(\s|[^\[\]])*     // Basicaly .*, but excluding brackets
(\[some-token\])  // A token [some-token]

如何阻止比赛继续过去黑名单?

我希望在我绘制三个箭头的地方发生这种情况。相当于Any字符,但不是此列表的内容:(UniquePrefixA | UniqueB | UniqueC)(如捕获组1中所示)。

我可能需要更好地理解消极前瞻,或者它是否适用于一组事物。 最重要的是,我想知道负面预测方法是否可以支持选项列表或者是否有更好的方法?如果答案是“你不能这样做,“那也很酷。

2 个答案:

答案 0 :(得分:1)

我认为,更容易维护的解决方案是将您的任务分为两部分:

  1. 从任何唯一的前缀开始查找文本的每个, 直到字符串的下一个或结尾。

  2. 处理每个这样的块,寻找你的一些令牌,也许吧 也是他们之间的内容。

  3. 执行第一项任务的正则表达式应包括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]

    就足够了

答案 1 :(得分:0)

要确保在(\s|[^\[\]])*等重复字符序列中不出现模式,请注意\s中包含[^\[\]]所以可能只是[^\[\]]*,是要预先添加在重复模式的左侧和内侧的负向前瞻(这是一个零{lenggh匹配断言,如^),以便检查每个字符:

((?!UniquePrefixA)(\s|[^\[\]]))*