将JavaScript RegEx转换为JSON格式

Convert a JavaScript RegEx into JSON format

本文关键字:JSON 格式 转换 JavaScript RegEx      更新时间:2023-09-26

我目前正在开发一个Safari扩展,它将利用Safari 9中提供的新的webkit内容拦截器功能。现在,这些拦截器的规则需要用JSON编写。

我即将成为扩展的后台脚本生成这样的JSON规则。我遇到的问题是,我不能正确地格式化一个正则表达式,它的作用是过滤url,是JSON兼容的。

假设我需要阻止URL包含"香蕉"、"橘子"或"苹果"的所有图像。我的正则表达式应该是这样的:

var url-filter = /banana|orange|apple/g;

现在是JSON格式的拦截器规则,缺少url过滤部分:

"action": {
   "type": "block"
    },
"trigger": {
   "url-filter": <JSON regex here>,
   "resource-type": ["image"],
   "load-type": ["third-party"]
    }
(更新)

我如何重写我的正则表达式是JSON兼容/准备,知道不支持更改?

正则表达式格式

触发器支持基于正则表达式过滤每个资源的url。

支持以下特性:

  • 匹配任何带有"。"的字符。
  • 使用范围语法[a-b]匹配范围。
  • 用"?","+"answers"*"。
  • 带括号的组

可以使用行首("^")和行尾("$")标记,但它们被限制为表达式的第一个和最后一个字符。例如,像"^bar$"这样的模式是完全有效的,而"(foo)?^bar$ "导致语法错误。

(更新BIS)

考虑到Safari实现的严格的CSP策略和缺乏对更改的支持,我最终将原始正则表达式转换为数组,然后通过循环动态生成JSON规则。

var regex = 'banana|orange|apple',
    filters = regex.split('|'),
    json_rules = [];
var Blocker = {
        build: function() {
            filters.forEach( function(filter) {
                var rule = {
                    action: {
                        'type': 'block'
                    },
                    trigger: {
                        'url-filter': filter,
                        'resource-type': ['image'],
                        'load-type': ['third-party']
                    }
                };
                json_rules.push(rule);
            });
            Blocker.set(JSON.stringify(json_rules));
        },
        init: function() {
            Blocker.build();
        },
        set: function (rule) {
            safari.extension.setContentBlocker(rule);
        }
};

根据您链接的文档,过滤器的值被视为正则表达式(例如,它们显示"url-filter": "evil-tracker''.js""url-filter": ".*")。

文档还说url-filter是不区分大小写的,所以您不必担心您可能想要使用的i标志。但是如果你想要一个区分大小写的,你可以添加"url-filter-is-case-sensitive": true

在这种情况下,您只需将正则表达式放在引号中,确保转义字符串字面量中需要转义的任何字符(例如,注意他们如何在"evil-tracker''.js"字符串中使用两个反斜杠,以便使regex为evil-tracker'.js)。

然而:表达式的问题是它们不支持更改。同样,从您链接的文档中:

该格式是JavaScript正则表达式的严格子集。从语法上讲,JavaScript支持的所有内容都是保留的,但解析器只接受其中的一个子集。不支持的表达式将导致解析错误。

支持以下特性:

  • 匹配任何带有"。"的字符。
  • 使用范围语法[a-b]匹配范围。
  • 用"?","+"answers"*"。
  • 带括号的组

可以使用行首("^")和行尾("$")标记,但它们被限制为表达式的第一个和最后一个字符。例如,像"^bar$"这样的模式是完全有效的,而"(foo)?^bar$ "导致语法错误。

请注意,他们不接受| (alternative)。

这告诉我你需要三个规则:一个用于banana,一个用于orange,一个用于apple