我正在设计一个HTML和JavaScript的正则表达式测试程序。用户将输入正则表达式,字符串,并通过单选按钮选择他们想要测试的功能(例如搜索,匹配,替换等),程序将在使用指定参数运行该功能时显示结果。当然会有额外的文本框用于替换等额外的参数。
我的问题是从用户那里获取字符串并将其转换为正则表达式。如果我说他们不需要在他们输入的正则表达式周围//
,那么他们就无法设置标记,例如g
和i
。所以他们必须在表达式周围有//
,但是如何将该字符串转换为正则表达式呢?它不能是文字,因为它是一个字符串,我不能将它传递给RegExp构造函数,因为它不是没有//
的字符串。有没有其他方法可以将用户输入字符串转换为正则表达式?我是否必须用//
解析正则表达式的字符串和标志然后以另一种方式构造它?我应该让他们输入一个字符串,然后单独输入标志吗?
答案 0 :(得分:558)
使用RegExp object constructor从字符串创建正则表达式:
var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
答案 1 :(得分:62)
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]);
答案 2 :(得分:13)
使用JavaScript RegExp object constructor。
var re = new RegExp("\\w+");
re.test("hello");
您可以将标志作为第二个字符串参数传递给构造函数。有关详细信息,请参阅文档。
答案 3 :(得分:12)
以下是单行: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/
答案 4 :(得分:9)
在我的情况下,用户输入有时被分隔符包围,有时不包围。因此我添加了另一个案例..
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);
}
答案 5 :(得分:2)
我建议你也为特殊标志添加单独的复选框或文本字段。这样很明显,用户不需要添加任何//
。在替换的情况下,提供两个文本字段。这将使您的生活更轻松。
为什么呢?因为否则一些用户会添加//
,而其他用户则不会。有些人会出现语法错误。然后,在剥离//
之后,你可能会得到一个语法上有效的正则表达式,它与用户的意图完全不同,导致奇怪的行为(从用户的角度来看)。
答案 6 :(得分:2)
当字符串无效或不包含标志等时,这也会起作用:
dynamic events = JsonConvert.DeserializeObject<dynamic>(post_data);
foreach(dynamic evt in events)
{
string emailType = evt.msg.metadata.email_type;
}
&#13;
答案 7 :(得分:2)
这是我的一个处理自定义分隔符和无效标志的班轮函数
function stringToRegex(s, m) {
return (m = s.match(/^([\/~@;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
}
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
答案 8 :(得分:1)
由于早期的答案,这个块可以作为将可配置字符串应用于RegEx ...以过滤文本的通用解决方案:
console.log($scope.stepTwo)
//I have:
//has_gst_yes_no=1
答案 9 :(得分:0)
您可以使用复选框请求标志,然后执行以下操作:
var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);
答案 10 :(得分:0)
如果您真的要将字符串转换为正则表达式,请尝试使用以下函数:
function String2Regex(s){return new RegExp(s.match(/\/(.+)\/.*/)[1], s.match(/\/.+\/(.*)/)[1]);}
您可以像这样使用它:
"abc".match(String2Regex("/a/g"))
> ["a"]
供参考,以下是格式化且更现代的版本:
const String2Regex = str => {
// Main regex
const main = str.match(/\/(.+)\/.*/)[1]
// Regex options
const options = str.match(/\/.+\/(.*)/)[1]
// Return compiled regex
return new RegExp(main, options)
}
答案 11 :(得分:-1)
我使用eval
解决了这个问题。
例如:
function regex_exec() {
var userInput = $("#regex").val();
// eval()
var patt = eval(userInput);
$("#result").val(patt.exec($("#textContent").val()));
}