如何将字符串化的正则表达式文字转换回常规表达式?

3
例如,我从服务器端在客户端获取了一个字符串:
"/hello\s{0,1}[-_.]{0,1}world|ls\b/gim"

在客户端中,我想将这个字符串转换为正则表达式对象。我尝试了。
new RegExp("/hello\s{0,1}[-_.]{0,1}world|ls\b/gim")

但是这样行不通,返回的对象是:
/\/hellos{0,1}[-_.]{0,1}world|ls\/gim/

总结一下: 我想要的是:
/hello\s{0,1}[-_.]{0,1}world|ls\b/gim.test('hello world') //true (correct behavior)

然而,这并不起作用:
new RegExp("/hello\s{0,1}[-_.]{0,1}world|ls\b/gim").test('hello world') //false

这个怎么做才是正确的?

2
eval("/hello\s{0,1}[-_.]{0,1}world|ls\b/gim").test('hello world'):heh - dandavis
由于您获得的是正则表达式语法(而不是字符串语法),因此无法直接将其与正则表达式构造函数一起使用。您可以使用 eval() 函数来实现。 - jfriend00
4个回答

6

RegExp 构造函数接受两个参数。第一个参数是要匹配的正则表达式的字面量源/模式(本质上是在正则表达式字面量中外部/之间的内容);第二个参数是要设置在该表达式上的标志(例如您的示例中的 gim)。我为您定义了一个助手函数,将按照您的格式转换成正则表达式的字符串。具有讽刺意味的是,我最终使用了另一个正则表达式来完成这个任务。

function regexFromString (string) {
    const match = /^([^/]*)(\/([a-z]*))?$/.exec(string)
    if(match.length <= 3)
        return new RegExp(match[1])
    return new RegExp(match[1], match[3])
}

var string = '/hello\\s{0,1}[-_.]{0,1}world|ls\\b/gim'

var regex = regexFromString(string)

console.log(regex instanceof RegExp) //=> true
console.log(regex)
console.log(regex.test('hello world')) //=> true


为什么不传递一个RegExp并省略额外的转义?你的脚本处理嵌入式斜杠吗?(没有^ | $) - dandavis
  1. 根据 OP 的说法:“我从服务器得到了一个字符串”。他没有得到一个正则表达式,因此在我的代码片段中我也不会从那里开始。
  2. 我明白你的意思关于斜杠。差点错过了,感谢你的指引。
- gyre
以下匹配正确:https://dev59.com/p5_ha4cB1Zd3GeqP27G6#69627874 - Constantin Schreiber

1

使用RegExp构造函数有些不同,以下是我认为你正在寻找的内容:

var x = new RegExp('hello\\s{0,1}[-_.]{0,1}world|ls\\b', 'gim').test("hello world");

console.log(x);

返回 true


0

晚回答

一种基于正则表达式本身的方法将从任何提供的字符串化正则表达式文字中捕获表达式的body和可选的flags部分。

正则表达式本身可能看起来像这样... /^\/(?<body>.*)\/(?<flags>[gimsuy]*)$/ ... 然后使用此正则表达式的故障转移方法可能如下所示...

// see ... [https://regex101.com/r/Ek881d/2]

function regexFromString(str) {
  const {
    body,
    flags,
  } = String(str)
    .match(/^\/(?<body>.*)\/(?<flags>[gimsuy]*)$/)
    ?.groups || {};

  return RegExp(body, (body && flags));
}

console.log(
  "regexFromString(String(/hello\s{0,1}[-_.]{0,1}world|ls\b/gim)).test('hello world') ? ",

  regexFromString(
    String(/hello\s{0,1}[-_.]{0,1}world|ls\b/gim)
  ).test('hello world')
);
console.log(
  "regexFromString('') ...",
  regexFromString('')
);

console.log(
  regexFromString('/foo/'),
  'this isfoook'.split(regexFromString('/foo/'))
);
console.log(
  regexFromString('/foo\\/bar/ig'),
  'this isfoo/barok'.split(regexFromString('/foo\\/bar/ig'))
);
console.log(
  regexFromString('/foo/bar/ig'),
  'this isfoo/barok'.split(regexFromString('/foo/bar/ig'))
);
.as-console-wrapper { min-height: 100%!important; top: 0; }


0
如果服务器向客户端提供正则表达式,则以下正则表达式匹配另一个正则表达式并将主体与标志分离以正确重构它。
function regexFromString(string) {
    const matchFlags = /^(.*)(\/([a-z]*))$/.exec(string)
    if (matchFlags && matchFlags.length >= 4)
        return new RegExp(matchFlags[1], matchFlags[3])

    return new RegExp(string)
}

var regex = regexFromString("^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})$/i")
console.log(regex.test("NtSbDeB1XxX"))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接