首页 > 解决方案 > RegEx 用于匹配仅由字母列表组成的单词

问题描述

给定一组单词,我需要知道哪些单词仅由一组字母组成。这个词不能有超过允许的字母,即使这个字母是验证集的一部分。

例子:

Char set: a, a, ã, c, e, l, m, m, m, o, o, o, o, t (fixed set)

Words set: mom, ace, to, toooo, ten, all, aaa (variable set)

结果:

mom = true
ace = true
to = true
toooo = true
ten = false (n is not in the set)
all = false (there is only 1 L in the set)
aaa = false (theres is only 2 A in the set)

如何在 Javascript 中生成这个正则表达式?(区分大小写不是问题)。

我试过这段代码没有成功:

var str = "ten"
var patt = new RegExp("^[a, a, ã, c, e, l, m, m, m, o, o, o, o, t]*");
console.log(patt.test(str));

标签: javascriptregexregex-lookaroundsregex-groupregex-greedy

解决方案


虽然我觉得这个任务更适合编写一些代码而不是使用正则表达式。但我能想到的一种方法是使用消极的前瞻性。

让我们以您的字符集为例,您允许的单词可以有以下字母,并且不超过列表中出现的数量。

a, a, ã, c, e, l, m, m, m, o, o, o, o, t

我们可以编写以下正则表达式,它使用负前瞻来丢弃包含比上述每个字符设置的字符数更多的字符串,最后使用允许的字符集从 1 到 N 个字符捕获单词,其中 N 是总数的字符。

^(?!([^a]*a){3})(?!([^ã]*ã){2})(?!([^c]*c){2})(?!([^e]*e){2})(?!([^l]*l){2})(?!([^m]*m){4})(?!([^o]*o){5})(?!([^t]*t){2})[aãcelmot]{1,14}$

解释:

  • ^- 字符串的开始
  • (?!([^a]*a){3})- 如果字符串中的数量为 3 或更多,则此负前瞻将拒绝输入,因为集合中a的总数a仅为 2。
  • (?!([^ã]*ã){2})ã- 同样,如果字符串中的数量为 2 或更多,因为设置的总数ã仅为 1 ,则此负前瞻将拒绝输入。
  • 以此类推所有角色
  • [aãcelmot]{1,14}- 这个字符集至少捕获一个到最多 14 个允许的字符,尽管我们也可以简单地写+为检查允许的最大字符数已经使用负前瞻完成。
  • $- 字符串结束

JS代码演示,

const arr = ['mom','ace','to','toooo','ten','all','aaa']

arr.forEach(x => console.log(x + " --> " +/^(?!([^a]*a){3})(?!([^ã]*ã){2})(?!([^c]*c){2})(?!([^e]*e){2})(?!([^l]*l){2})(?!([^m]*m){4})(?!([^o]*o){5})(?!([^t]*t){2})[aãcelmot]{1,14}$/.test(x)))


推荐阅读