【问题标题】:How to check if the input string is a valid Regular expression?如何检查输入字符串是否是有效的正则表达式?
【发布时间】:2013-06-19 12:06:04
【问题描述】:

在 JavaScript 中,如何检查字符串是否是可以编译的正确正则表达式?

例如,当您执行以下 javascript 时,会产生错误。

var regex = new RegExp('abc ([a-z]+) ([a-z]+))');
// produces:
// Uncaught SyntaxError: Invalid regular expression: /abc ([a-z]+) ([a-z]+))/: Unmatched ')'

如何确定一个字符串是否是有效的正则表达式?

【问题讨论】:

  • 您需要一个正则表达式来测试一个正则表达式?大声笑
  • 请清楚说明您的代码,我们将为您提供帮助
  • 我想检查输入字符串是否是有效的正则表达式
  • 为什么这是“不是一个真正的问题”或“关闭”?还是负面反馈?我在这里找到了答案,与描述的确切问题一样!
  • 完全正确.. 除非它被编辑过,否则这个问题没有任何含糊之处 - 有效的表达式是那些可以编译的表达式。由于我们在这里讨论的是 javascript,因此只有假设这意味着 ES 表达式才有意义。

标签: javascript regex


【解决方案1】:

您可以使用try/catchRegExp 构造函数:

var isValid = true;
try {
    new RegExp("the_regex_to_test_goes_here");
} catch(e) {
    isValid = false;
}

if(!isValid) alert("Invalid regular expression");

【讨论】:

  • @Jak:如果您提供更多关于“不起作用”的信息,那么我们可能会为您提供帮助。但只说“它不起作用”什么都没有。你尝试什么输入?你得到什么输出?你得到一个不同的错误吗?
  • 我替换了我的文本框值而不是 the_regex_to_test_goes_here 但它不能确定文本框值是否有效。我的问题信息现在够了吗?
  • @JakSamun:发布一个 jsfiddle.com 链接,其中包含您所做的事情,并告诉我们结果与您的预期有何不同。
  • @DmitryDavydov 正则表达式在技术上确实是“正确的”,尽管它非常令人困惑。请注意,您引用的行为是 POSIX standard特殊字符 ... 在括号表达式中将失去其特殊含义)。
  • 在 Chrome 63 中不起作用 - 似乎在构造函数中接受任何值而不抛出。
【解决方案2】:

这是一个检查两种类型的正则表达式、字符串或模式的有效性的小函数:

function validateRegex(pattern) {
    var parts = pattern.split('/'),
        regex = pattern,
        options = "";
    if (parts.length > 1) {
        regex = parts[1];
        options = parts[2];
    }
    try {
        new RegExp(regex, options);
        return true;
    }
    catch(e) {
        return false;
    }
}

例如,用户将能够同时测试test/test/gHere 是一个工作小提琴。

【讨论】:

  • 这个函数允许输入任意字符串,所以我不确定这是否符合操作的要求
  • (你投反对票了吗?哈哈)我的答案和另一个答案基本上做同样的事情,除了我还考虑了模式中可能的选项。而且,老实说,OP 想要的只是“检查输入字符串是否是有效的正则表达式”;对输入长度没有特别的限制,因此任何字符串都可以作为输入传递。此外,我完全按照他的要求做,甚至返回正确的真值或假值。
  • 您没有考虑到带有 / 作为其一部分的正则表达式。
【解决方案3】:
function isRegExp(regExp){
          try {
                new RegExp(regExp);
              } catch(e) {
                return false
              }
         return true
    }

ex:
isRegExp(/@(\w+)/g) = true

【讨论】:

  • 您可以对您发布的代码添加一些解释吗? “简洁是可以接受的,但更全面的解释更好。” -How do I write a good answer?
  • 我只是这里的初学者,我会即兴回答给定代码的更易于理解的解释。为此,所有实验代码都处于离线状态,让我将所有代码推送到 github 上,并在此处返回参考链接。谢谢#HappyCoding
  • 这或多或少是 2013 年原始答案的副本..
【解决方案4】:

此函数可以将“/”字符作为正则表达式中的普通字符处理,并且还可以考虑在是普通字符串时转义。它总是返回一个正则表达式,如果不是一个好的正则表达式字符串,则返回 null。

function getRegex(regex) {
    try {
        regex = regex.trim();
        let parts = regex.split('/');
        if(regex[0] !== '/' || parts.length< 3){
          regex = regex.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); //escap common string
          return new RegExp(regex);
        }

        const option =parts[parts.length - 1];
        const lastIndex = regex.lastIndexOf('/');
        regex = regex.substring(1, lastIndex);
        return new RegExp(regex, option);
    } catch (e) {
        return null
    }
}

console.log(getRegex('ab/c'))
let htmlStartTag = getRegex('/<(?!/)(?!br)(.+?)(?<!/)>/mgs');
console.log(htmlStartTag)
let result = `</button><input id="warehouse-search-field-tablet"
class="form-control search-field"
 title="Warehouse Search Field" name="location" type="search" value="">content`.matchAll(htmlStartTag);
 console.log([...result])

【讨论】:

    【解决方案5】:

    问题已解决,但如果有人需要定义字符串是有效的 RegExp 还是根本不是 RegExp

    您可以使用new Function() 并在函数体内部使用try ... catchnew RegExp() 进行模板化,如前所述。

    有一个带有解释的sn-p:

    const isRegExp = (string) => {
        try {
            return new Function(`
                "use strict";
                try {
                    new RegExp(${string});
                    return true;
                } catch (e) {
                    return false;
                }
            `)();
        } catch(e) {
            return false;
        }
    };
    
    // Here the argument 'simplyString' shall be undefined inside of the function
    // Function(...) catches the error and returns false
    console.log('Is RegExp valid:', isRegExp('simplyString'));
    
    // Here the argument shall cause a syntax error
    // isRegExp function catches the error and returns false
    console.log('Is RegExp valid:', isRegExp('string which is not a valid regexp'));
    
    // Here the argument is not a valid RegExp, new RegExp(...) throws an error
    // Function(...) catches the error and returns false
    console.log('Is RegExp valid:', isRegExp('abc ([a-z]+) ([a-z]+))'));
    
    // Valid RegExp, passed as a string
    console.log('Is RegExp valid:', isRegExp('/^[^<>()[\]\\.,;:\s@\"]$/'));
    
    // Valid RegExp, passed as a RegExp object
    console.log('Is RegExp valid:', isRegExp(/^[^<>()[\]\\.,;:\s@\"]$/));
    
    // Howewer, the code injection is possible here
    console.log('Is RegExp valid:', isRegExp(');console.log("This is running inside of the Function(...) as well"'));

    【讨论】:

      【解决方案6】:

      这里没有一个答案满足我检查字符串是否是其他语言(主要是 php)的有效正则表达式的需要,因为它们要么忽略标志、分隔符或转义特殊字符,所以我制作了自己的函数

      function isValidRegex(s) {
        try {
          const m = s.match(/^([/~@;%#'])(.*?)\1([gimsuy]*)$/);
          return m ? !!new RegExp(m[2],m[3])
              : false;
        } catch (e) {
          return false
        }
      }
      
      console.log(isValidRegex('abc')) //False
      console.log(isValidRegex('/abc/')) //True
      console.log(isValidRegex('/ab#\/[c]/ig')) //True
      console.log(isValidRegex('@ab#\/[c]@ig')) //Special delimiters: True
      console.log(isValidRegex('/ab\/[c/ig')) //False
      console.log(isValidRegex('/abc/gig')) //False

      你也可以派生这个函数来将字符串转换为 RegExp 对象

      function stringToRegex(s) {
         const m = s.match(/^([/~@;%#'])(.*?)\1([gimsuy]*)$/);
         return m ? new RegExp(m[2], m[3]) : new RegExp(s);
      }
      
      console.log(stringToRegex('abc'))
      console.log(stringToRegex('/abc/'))
      console.log(stringToRegex('/ab#\/[c]/ig'))
      console.log(stringToRegex('@ab#\/[c]@ig'))
      try {
        console.log(stringToRegex('/ab#\/[c/ig'))
      } catch (e) {
        console.log('Not a valid regex')
      }

      【讨论】:

        猜你喜欢
        • 2013-11-07
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-29
        • 2010-10-24
        相关资源
        最近更新 更多