4

我想替换字符串中的一些字符,例如

console.log( 
    "truefalse".replace("e","E")
)

但是使用jsfuck约定,其中只允许 6 个字符:[]()!+,为了提高可读性,这里也允许带有字母 az 和 AZ 以及数字 0-9 的 JS 字符串(因为很容易将这些字符串转换为 6 字符的 jsf 代码)。所以我可以这样写

console.log(
  "truefalse"["replace"]("e","E")
)

但在上面的代码中,我使用了禁止字符 - 逗号:,。因此,我使用trincot 在这里发现的 2 个(以及更多)参数调用函数的技术,如下所示

console.log(
  "truefalse"["split"]()["concat"]([["e"]["concat"]("E")])
    ["reduce"](""["replace"]["apply"]["bind"](""["replace"]))
)

现在我想在替换函数中使用正则表达式并使用上述限制编写代码

console.log(
  "truefalse"["replace"](/e/g,"E")
)

但我不知道如何处理正则表达式部分/e/g?不使用任何类型的“eval”(字符串被解释为代码)就可以做到这一点?

4

1 回答 1

2

我看不到在RegExp不评估代码的情况下访问构造函数的方法,例如Function构造函数:

""["replace"]["constructor"]("return RegExp")()

但考虑到这一点

  • 如果您需要替换多个匹配项,您可以使用replaceAll带有字符串作为第一个参数的方法
  • 方法matchmatchAll可以与字符串参数一起使用,并且RegExp将为该字符串动态创建一个对象,就像您调用了.match(RegExp(str))

因此,例如,如果您需要将字符串拆分为四个字符的块,则可以使用.matchAll("...."). 只有两件事要做更多:

  • 作为matchAll返回一个迭代器,你需要从中创建一个数组;像Array.from.
  • 由于您无法直接访问该Array变量,因此您可以[].constructor改用。
  • 返回的块在嵌套数组中,需要展平。您可以为此联系.flat()电话。

这样就变成了

console.log(
  []["constructor"]["from"]("abcdefghijkl"["matchAll"]("...."))["flat"]()
);

于 2020-08-26T21:25:30.720 回答