繁体   English   中英

正则表达式将IP与jsonschema中的掩码匹配

[英]regex to match IP with mask in a jsonschema

这里有一个很好的解决方案可将IP与掩码匹配,例如192.168.0.1/24 我添加了来自https://regex101.com/的建议以逃避斜线,它看起来像这样:

((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}\/(?:\d|[12]\d|3[01])$

这肯定在regex101上起作用。

它需要存在一个json文件(jsonschema文件)中,但似乎包含非法内容。 无法弄清楚它是什么,已经看过thisthisthis ,并尝试使用ujson代替此处建议的json(在python中),但没有任何效果。

以下包含该正则表达式的jsonschema:

{
    "comment": "ipv4 with a mask",
    "data": {
        "network": {
        }
    },
    "schema": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "ipv4 with a mask",
        "type": "object",
        "properties": {
            "subnet": {
                "title": "subnet",
                "type": "string",
                "pattern": "((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}\/(?:\d|[12]\d|3[01])$"
            }
        }
    }
}

...不幸的是甚至无法解析。 Python在说:

JSONDecodeError: Invalid \escape: line 16 column 33 (char 380)

我一直在使用库fastjsonschema来检查这些内容,但是甚至无法解析json并达到目标。

有谁知道如何解决此问题,以某种方式使该正则表达式在jsonschema中起作用?

对于JSON,您需要使用另一个反斜杠对每个反斜杠\\进行转义:

((^|\\.)((25[0-5])|(2[0-4]\\d)|(1\\d\\d)|([1-9]?\\d))){4}\\/(?:\\d|[12]\\d|3[01])$

因此,在JSON模式中,它看起来像:

"pattern": "((^|\\.)((25[0-5])|(2[0-4]\\d)|(1\\d\\d)|([1-9]?\\d))){4}\\/(?:\\d|[12]\\d|3[01])$"

无论如何,您在链接中找到的正则表达式与数字分组不太匹配。 用一些示例进行尝试- 完全匹配是正确的,但是返回的包括带数字的点或仅包含点。

如果您想要IP地址的所有部分,而不仅仅是一个完整的匹配,那么这里是基于此的正则表达式。 我包括了一个可选子网掩码的匹配项:

^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
(?:\/(\d|[12]\d|3[01]))?$

(删除为方便阅读而添加的换行符。) 此处演示 只有前3个地址应该匹配,其余的不应该匹配。

如果只需要完整匹配,而不是单个部分,请使用以下命令:

^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
(?:\/(?:\d|[12]\d|3[01]))?$

您不会相信,但是2个反斜杠是不够的!

它不能与2个反斜杠一起使用,它需要3或4个,所以将与3个反斜杠一起使用

不得不花几个小时来实现这一点,但是从@TimPietzcker找到了这个答案 ,它说:

您需要对正则表达式使用转义反斜杠,然后再次对字符串处理器进行转义。

因此, 工作代码如下所示(略微调整了原始架构):

import json    
import fastjsonschema

schema = '''{
    "data": [{"subnet": "192.168.1.1/24"}],
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
                "subnet": {
                    "title": "subnet",
                    "type": "string",
                    "pattern": "((^|\\\.)((25[0-5])|(2[0-4]\\\d)|(1\\\d\\\d)|([1-9]?\\\d))){4}\\\/(?:\\\d|[12]\\\d|3[01])$"
                }
            }
        }
    }''' 

schema = json.loads(schema)
validate = fastjsonschema.compile(schema)

def check_subnets(testcase):
    try: 
        validate([{"subnet": testcase}])
        print("yes a subnet")
    except fastjsonschema.JsonSchemaException:
        print("not a subnet")    

然后进行一些测试:

>>> check_subnets("192.168.0.1/24") 
yes a subnet
>>> check_subnets("192.168.0.1/50")
not a subnet
>>> check_subnets("192.168.0.1")
not a subnet
>>> check_subnets("192.168.0.900/24")
not a subnet

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM