这是一个糟糕的正则表达式模式吗

Is this a bad regex pattern?

本文关键字:正则表达式 模式 一个      更新时间:2023-09-26

在最近与初级JavaScript开发人员的一次谈话中,我提到了以下技术,用于减少使用OR操作数的费力if/else块:

if (/^(cat|dog|horse)$/.test(animal)) { ... }

而不是

if (animal == 'cat' || animal == 'dog' || animal == 'horse') { ... }

我从来没有遇到过这个问题,但有人认为这是一个糟糕的设计模式,但没有详细说明原因。

在我看来,这是"太聪明了",在这样做的过程中,您引入了几个新的潜在故障点(在regex语法中),并降低了代码的表达性/惯用性。如果操作数从'cat'变为动态或可变,您也会遇到困难。

通常,在做这样的事情时,我只介绍了一个数组:

if (['cat', 'dog', 'horse'].indexOf(animal) != -1) { ... }

不过,老实说,这一切都是可笑的主观,所以我无法给你"正确"的答案。

通常在这一点上,我会介绍性能问题,但实际上,由于只需要扫描输入一次,您可能有一个更快的解决方案。这将取决于正则表达式本身的解析速度。

毫无疑问,在这种情况下,我更喜欢正则表达式的方式,而不是感谢有一长串的比较。性能方面,我也认为regex不会明显低于多次比较(想象一下你的动物的30-40比较)。

Regex还为您提供了其他好处,如检查忽略大小写匹配或与单词边界进行比较(对于输入是某些文本的一部分的情况),而这将需要额外的代码来进行字符串比较。

构建正则表达式比进行一些字符串比较更昂贵,但如果它能使代码更清晰,并且性能不受影响(当然是通过评测!),那么我认为这是可以的。

这是基于意见的,但需要提出的一些要点是:

代码应该可读,而不是一定要短。

Regex更容易出错,例如:如果忘记了$,这将与horses 匹配

如果没有文档,阅读代码重构代码的人可能不会感到痛苦——它的目的:

  • 它应该区分动物吗?^cat|dog|horse$
  • 它应该区分动物数量吗?^cat|dog|horse

添加更多变体可能会有问题,即:

if (animal == 'cat' || animal == 'dog' || animal == someUserInputtedAnimal)

解决方案:

对于许多if语句,使用开关或"true"开关:

switch (animal)
{
    case 'cat':
        break;
    case 'dog':
        break;
    case 'horse':
        break;
}
switch (true)
{
    case animal == 'cat':
        break;
    case animal == 'dog':
        break;
    case animal == 'horse':
        break;
    case someRandomAnimal == ressurected:
        break;
}