将用户输入字符串转换为正则表达式

IT技术 javascript html regex
2021-01-14 17:05:08

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

我的问题是从用户那里获取字符串并将其转换为正则表达式。如果我说他们不需要//在他们输入的正则表达式周围's ,那么他们就不能设置标志,比如gand i所以他们必须//在表达式周围's,但我如何将该字符串转换为正则表达式?它不能是文字,因为它是一个字符串,我不能将它传递给 RegExp 构造函数,因为它不是没有//'s的字符串有没有其他方法可以将用户输入字符串转换为正则表达式?我是否必须用//'s解析正则表达式的字符串和标志,然后以另一种方式构造它?我应该让他们输入一个字符串,然后分别输入标志吗?

6个回答

使用RegExp 对象构造函数从字符串创建正则表达式:

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
拥有带有输入字段的在线工具会很好
2021-03-11 17:05:08
这样做时,您必须转义反斜杠,例如 var re = new RegExp("\\w+");
2021-03-11 17:05:08
@holms regex101.com也是一个很棒的正则表达式在线工具
2021-03-18 17:05:08
@JDSmith 我在你的例子中并不是这个意思。我的意思是,如果您希望双引号成为硬编码的正则表达式的一部分,则需要转义双引号。显然,如果字符串位于像<input>HTML 标记那样的变量中,则这些都不适用var re = new RegExp("\"\\w+\"");是使用正则表达式构造一个硬编码的正则表达式的一个例子和双引号的逸出必要的。我所说的变量中的字符串的意思是你可以这样做var re = new RegExp(str);并且str可以包含双引号或反斜杠而不会出现问题。
2021-04-03 17:05:08
我花了一段时间才看到不需要尾部斜杠
2021-04-08 17:05:08
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

或者

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
请注意,用户可以输入任意数量的标志,例如:/foo/ggggg在第一个示例中,您可以将flags替换更改replace('/.*\/(?!.*(.).*\1)([gimy]*)$/', '$2'). 或者对第二个示例使用以下正则表达式^\/(.*)\/(?!.*(.).*\2)([gimy]*)$,将标志放在匹配组 3 中。
2021-03-11 17:05:08
或者让 RegExp 构造函数失败,“在正则表达式中尾随 \”,而不是编写一个复杂的解析器。
2021-03-13 17:05:08
您应该考虑/\/识别出像这样的无效输入
2021-03-29 17:05:08

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

我是从escape-string-regexp NPM module得到的。

尝试一下:

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

使用JavaScript RegExp 对象构造函数

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

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

在我的情况下,用户输入 somethimes 被分隔符包围,有时没有。因此我添加了另一个案例..

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);
}
@ZomoXYZ 不要使用拆分,它不会处理/正则表达式中的转义
2021-03-25 17:05:08
你可以做得更好: function stringToRegex(s, m) { return (m = s.match(/^(.)(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3]) : new RegExp(s); }
2021-03-31 17:05:08
您始终可以使用该.split()函数而不是长正则表达式字符串。 regParts = inputstring.split('/')这将使regParts[1]正则表达式字符串和regParts[2]分隔符(假设正则表达式的设置是/.../gim)。您可以检查是否有带有regParts[2].length < 0.
2021-04-10 17:05:08