Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将用户输入字符串转换为正则表达式_Javascript_Html_Regex - Fatal编程技术网

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

Javascript 将用户输入字符串转换为正则表达式,javascript,html,regex,Javascript,Html,Regex,我正在用HTML和JavaScript设计一个正则表达式测试程序。用户将输入一个正则表达式、一个字符串,并通过单选按钮选择要测试的函数(例如搜索、匹配、替换等),程序将在使用指定参数运行该函数时显示结果。自然会有额外的文本框来替换额外的参数等等 我的问题是从用户那里获取字符串并将其转换为正则表达式。如果我说他们不需要在他们输入的正则表达式周围有/,那么他们就不能设置标志,比如g和I。所以他们必须在表达式周围有/,但是我如何才能将该字符串转换为正则表达式呢?它不能是文本,因为它是一个字符串,我不能

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

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

使用

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

使用从字符串创建正则表达式:

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;

我建议您也为特殊标志添加单独的复选框或文本字段。这样,用户就不需要添加任何
/
。如果是替换,请提供两个文本字段。这会让你的生活轻松很多


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

您可以使用复选框请求标志,然后执行以下操作:

var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);


在我的例子中,用户输入有时被分隔符舍入,有时不舍入。因此,我又增加了一个案例

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);
}

多亏了前面的回答,这个模块可以作为将可配置字符串应用到正则表达式中的通用解决方案。。用于过滤文本:

var permittedChars = '^a-z0-9 _,.?!@+<>';
permittedChars = '[' + permittedChars + ']';

var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);

log.debug ('strFilterRegEx: ' + strFilterRegEx);

strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!@+]/ig, '');
var permittedChars='^a-z0-9,.?!@';
permittedChars='['+permittedChars+']';
var标志='gi';
var strFilterRegEx=新的RegExp(permittedChars,flags);
log.debug('strFilterRegEx:'+strFilterRegEx);
strVal=strVal.replace(strFilterRegEx',);
//这将取代硬代码solt:
//标准偏差=标准偏差。更换(/[^a-z0-9,.?!@+]/ig');

这里有一行代码:
str.replace(/[\\\\{}()[\]^$+*?.]/g,'\\$&')

我是从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
函数str2reg(标志='u'){
return(…args)=>newregexp(escapeStringRegExp(evalTemplate(…args))
,国旗)
}
函数evalTemplate(字符串,…值){
设i=0
返回strings.reduce((str,string)=>`${str}${string}${
i/example\.com/u

当字符串无效或不包含标志等时,此操作也有效:

函数regExpFromString(q){
让flags=q.replace(/.*\/([gimuy]*)$/,“$1”);
如果(标志===q)标志='';
let pattern=(flags?q.replace(新的RegExp('^/(.*?/'+flags+'$),'$1'):q);
尝试{returnnewregexp(pattern,flags);}catch(e){returnnull;}
}
log(regExpFromString('\\bword\\b'));
log(regExpFromString('\/\\bword\\b\/gi');

尝试使用以下功能:

const stringToRegex=str=>{
//主正则表达式
常量main=str.match(/\/(.+)\/.*/)[1]
//正则表达式选项
const options=str.match(/\/.+\/(.*)/)[1]
//编译正则表达式
返回新的RegExp(main,options)
}
您可以这样使用它:

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

我使用
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()));
    }

下面是我的一行函数,它处理自定义分隔符和无效标志

函数stringToRegex(s,m){
return(m=s.match(/^([\/~@;%#'])(.*)\1([gimsuy]*)$/)?新的RegExp(m[2],m[3]。拆分(“”)。过滤器((i,p,s)=>s.indexOf(i)==p)。连接(“”)):新的RegExp(s);
}
log(stringToRegex('/(foo)?\/bar/i');
log(stringToRegex('#(foo)\\/bar##gi')//自定义分隔符
log(stringToRegex('#(foo)\\/bar##gig')//重复的标志被过滤掉
console.log(stringToRegex('/(foo)?\/bar');//作为字符串处理

console.log(stringToRegex('gig'));//作为字符串< /代码>对待,您应该考虑到一个无效的输入,如<>代码> /\/<代码>。或者让ReGEXP构造函数失败,“在正则表达式中拖尾”,而不是编写一个复杂的解析器。注意,用户可以根据需要输入尽可能多的标志,例如:<代码> /Foo/GGGG。在第一个示例中,您可以将
标志
replace更改为
replace('/.\/(?!.*()..*\1)([gimy]*)$/','$2')
。或者将下面的正则表达式用于第二个示例
^\/(.*)\/(?!*().*\2)([gimy]*)$
,将标志放在匹配组3中。如果有带输入字段的联机工具就好了。这样做时,必须转义反斜杠,例如
var re=new RegExp(\\w+)
@holms也是一个很棒的regex在线工具。我花了一段时间才发现后面没有斜杠required@JDSmith我在你的例子中不是故意的。我的意思是,如果你想让它们成为正则表达式的一部分,只要它是硬编码的,就需要对双引号进行转义。显然,如果字符串位于类似于
HTML标记的变量中,则所有这些都不适用<代码>变量re=newregexp(“\”\\w+\”)
是使用RegExp构造函数和
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
    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()));
    }