78

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

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

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

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

4

6 回答 6

103

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

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

if(!isValid) alert("Invalid regular expression");
于 2013-06-22T12:44:19.690 回答
6

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

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/g是一个工作小提琴。

于 2013-06-22T13:02:48.497 回答
0

此函数可以将 '/' 字符作为正则表达式中的普通字符处理,并且还可以考虑转义 when 是一个公共字符串。它总是返回一个正则表达式,如果不是一个好的正则表达式字符串,则返回 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])

于 2020-05-06T02:41:39.370 回答
0

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

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

有一个带有解释的片段:

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"'));

于 2020-05-09T10:10:59.020 回答
0

这里没有一个答案满足我检查字符串是否是其他语言(主要是 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')
}

于 2021-03-23T19:12:04.307 回答
-1
function isRegExp(regExp){
          try {
                new RegExp(regExp);
              } catch(e) {
                return false
              }
         return true
    }

ex:
isRegExp(/@(\w+)/g) = true
于 2019-08-19T16:52:11.243 回答