我正在用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?


当前回答

尝试使用下面的函数:

const stringToRegex = str => {
    // Main regex
    const main = str.match(/\/(.+)\/.*/)[1]
    
    // Regex options
    const options = str.match(/\/.+\/(.*)/)[1]
    
    // Compiled regex
    return new RegExp(main, options)
}

你可以这样使用它:

"abc".match(stringToRegex("/a/g"))
//=> ["a"]

其他回答

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

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

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

在我的例子中,用户输入有时被分隔符包围,有时没有。所以我又加了一个案例。

var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
    // the parsed pattern had delimiters and modifiers. handle them. 
    var regexp = new RegExp(regParts[1], regParts[2]);
} else {
    // we got pattern string without delimiters
    var regexp = new RegExp(inputstring);
}

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

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

var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

or

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);

我发现@Richie Bendall的解决方案非常干净。我添加了一些小的修改,因为当传递非正则字符串时,它会崩溃并抛出错误(也许这就是你想要的)。

const stringToRegex = (str) => {
const re = /\/(.+)\/([gim]?)/
const match = str.match(re);
if (match) {
    return new RegExp(match[1], match[2])
}

}

使用(gim) ?在模式中,如果匹配的[2]值无效,将忽略它。你可以省略[gim]?模式,如果您希望在正则表达式选项无效时抛出错误。