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

时间:2009-05-17 14:20:18

标签: javascript html regex

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

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

12 个答案:

答案 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;
&#13;
&#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()));
    }