有没有更聪明的方式编写此RegExp?

时间:2019-09-28 19:07:50

标签: javascript regex

考虑以下正则表达式:/^(B|C|AB|AC|BC|ABC)$/。它仅接受包含BC(包括或)的字符串,可以选择在其后加上A。尽管它可以正常工作,将所有可接受的字符串一一列出,但显然不是一个非常可扩展的解决方案,尤其是考虑到ABC可以替代更长的时间词组。我的问题是:有没有办法写一个等效的正则表达式,其中ABC只出现一次?

4 个答案:

答案 0 :(得分:2)

/^(B|C|AB|AC|BC|ABC)$/

直接等于

/^(A(?:BC?|C)|BC?|C)$/

后者快了10倍。

答案 1 :(得分:0)

您可以使用

^A?(BC?|C)$

与您问题中的表达式相比,它匹配

B C AB AC ABC

但不匹配

ACB AAB ABA AAC ABCC

答案 2 :(得分:-1)

/^(B|C|AB|AC|BC|ABC)$/

由于A是可选前缀,我们可以将其取出并使用?

/^A?(B|C|BC)$/

如果要摆脱BC的重复,可能有一种使用正则表达式subroutines的方法。不幸的是,这些似乎在JS中不起作用!错误匹配之后的后处理如何?

/^A?(B?)(C?)$/

然后检查两个捕获组中的至少一个是否匹配:

let re = /^A?(B?)(C?)$/;
for (let str of [
  "A",
  "B",
  "C",
  "AB",
  "AC",
  "ABC",
  "BAC",
  "CBA",
  "AAB",
  "ABBC"
]) {
  let groups = str.match(re);
  let match = (!!groups && (!!groups[1] || !!groups[2]));
  console.log(str, match);
}

答案 3 :(得分:-2)

我们在这里!

var regex = RegExp('^A{0,1}(BC{0,1}|C)$');
// Good
console.log('GOOD');
console.log(regex.test('AB'));
console.log(regex.test('AC'));
console.log(regex.test('ABC'));
console.log(regex.test('B'));
console.log(regex.test('C'));

// Wrong
console.log('WRONG');
console.log(regex.test('A'));
console.log(regex.test('CB'));
console.log(regex.test('ACB'));
console.log(regex.test('CAB'));
console.log(regex.test('ABX'));
console.log(regex.test('Z'));