我正在用HTML和JavaScript设计一个正则表达式测试器。用户将输入一个正则表达式,一个字符串,并通过单选按钮选择他们想要测试的函数(例如搜索,匹配,替换等),当该函数以指定的参数运行时,程序将显示结果。自然会有额外的文本框用于替换额外的参数等等。

My problem is getting the string from the user and turning it into a regular expression. If I say that they don't need to have //'s around the regex they enter, then they can't set flags, like g and i. So they have to have the //'s around the expression, but how can I convert that string to a regex? It can't be a literal since its a string, and I can't pass it to the RegExp constructor since its not a string without the //'s. Is there any other way to make a user input string into a regex? Will I have to parse the string and flags of the regex with the //'s then construct it another way? Should I have them enter a string, and then enter the flags separately?


当前回答

这是一个一行程序:str.replace (/[|\\{}()[\]^$+*?.) / g, ' \ \ $ &’)

我从escape-string-regexp NPM模块中得到的。

尝试一下:

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/

使用带标记的模板文字支持:

function str2reg(flags = 'u') {
    return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
        , flags)
}

function evalTemplate(strings, ...values) {
    let i = 0
    return strings.reduce((str, string) => `${str}${string}${
        i < values.length ? values[i++] : ''}`, '')
}

console.log(str2reg()`example.com`)
// => /example\.com/u

其他回答

我用eval来解决这个问题。

例如:

    function regex_exec() {

        // Important! Like @Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk. 
        var regex = $("#regex").val();

        // eval()
        var patt = eval(userInput);

        $("#result").val(patt.exec($("#textContent").val()));
    }

我建议您还为特殊标志添加单独的复选框或文本框。这样很明显,用户不需要添加任何//。在替换的情况下,提供两个文本字段。这会让你的生活轻松很多。

为什么?因为否则一些用户会添加// s,而其他用户不会。有些会犯语法错误。然后,在去掉//之后,您可能会得到一个语法上有效的正则表达式,但它与用户想要的完全不同,从而导致奇怪的行为(从用户的角度来看)。

使用JavaScript的RegExp对象构造函数。

var re = new RegExp("\\w+");
re.test("hello");

可以将标志作为第二个字符串参数传递给构造函数。详细信息请参见文档。

下面是一个处理自定义分隔符和无效标志的线性函数

// One liner var stringToRegex = (s, m) => (m = s.match(/^([\/~@;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s); // Readable version function stringToRegex(str) { const match = str.match(/^([\/~@;%#'])(.*?)\1([gimsuy]*)$/); return match ? new RegExp( match[2], match[3] // Filter redundant flags, to avoid exceptions .split('') .filter((char, pos, flagArr) => flagArr.indexOf(char) === pos) .join('') ) : new RegExp(str); } console.log(stringToRegex('/(foo)?\/bar/i')); console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out console.log(stringToRegex('/(foo)?\/bar')); // Treated as string console.log(stringToRegex('gig')); // Treated as string

这是一个一行程序:str.replace (/[|\\{}()[\]^$+*?.) / g, ' \ \ $ &’)

我从escape-string-regexp NPM模块中得到的。

尝试一下:

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/

使用带标记的模板文字支持:

function str2reg(flags = 'u') {
    return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
        , flags)
}

function evalTemplate(strings, ...values) {
    let i = 0
    return strings.reduce((str, string) => `${str}${string}${
        i < values.length ? values[i++] : ''}`, '')
}

console.log(str2reg()`example.com`)
// => /example\.com/u