如何检查输入字符串是否是有效的正则表达式?

如何在 JavaScript 中检查一个字符串是否是要编译的正则表达式?

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

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

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

51032 次浏览

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

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


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

下面是一个小函数,它检查两种正则表达式、字符串或模式的有效性:

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

function isRegExp(regExp){
try {
new RegExp(regExp);
} catch(e) {
return false
}
return true
}


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

这个函数可以将’/’字符作为正则表达式中的普通字符进行处理,还可以考虑在作为公共字符串时转义。它将始终返回一个正则表达式,如果不是一个好的正则表达式字符串,则返回 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])

这个问题已经解决了,但是如果有人需要定义字符串,那么这个字符串要么是有效的 正则表达式,要么根本就不是 正则表达式

如前所述,可以在函数体内部使用 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"'));

这里的所有答案都不能满足我检查字符串是否是其他语言(大部分是 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')
}