【问题标题】:How to validate regex-field using JSON schema如何使用 JSON 模式验证正则表达式字段
【发布时间】:2019-02-25 10:56:36
【问题描述】:

例如,我有带有字段 NameRegex 的 JSON:

{
   "NameRegex": ".*abc+"
}

用户经常忘记“。”在“*”之前或犯类似错误。是否可以使用 json 模式验证此字段中指定的正则表达式的正确性?

【问题讨论】:

    标签: .net json jsonschema


    【解决方案1】:

    不幸的是,没有很好的方法来验证正则表达式,因为几乎任何字符串(甚至这个答案)都可能是有效的正则表达式。即使你有一个好的方法,正则表达式验证也是基于实现的,并且与 JSON Schema 的要求脱节。例如,我的实现(在.Net 中)将正则表达式处理委托给Regex 类。如果它失败了,那么你会得到一个运行时异常。

    您实际上可以做的最好的事情是在部署到生产之前广泛测试您的正则表达式。

    这里有几个不错的测试站点:

    还有很多其他的。

    【讨论】:

    • 不,*abc+ 不是有效的正则表达式,因为在 * 之前没有什么可重复的
    • @erikkallen 我已经扩展了我的答案。
    【解决方案2】:

    我不认为你可以使用 JSON 模式来做到这一点,但你可以在代码中通过挂钩到反序列化过程来做到这一点。在那里,您将通过尝试从中构造 Regex 对象来验证 NameRegex 字符串是否是有效的正则表达式,如果无效则抛出异常。

    为此,请在目标类中创建一个接受 StreamingContext 的验证方法,并使用 [OnDeserialized] 属性对其进行装饰。用该方法编写您的验证代码。例如:

    public class Foo
    {
      public string NameRegex { get; set; }
    
      [OnDeserialized]
      internal void OnDeserializedMethod(StreamingContext context)
      {
        try
        {
          //ensure NameRegex is a valid regex
          var r = new Regex(NameRegex);
        }
        catch
        {
          //throw whatever exception is appropriate for you
          throw new InvalidDataException(
             $"'{NameRegex}' is not a valid regular expression.");
        }
      }  
    }
    

    如果验证失败,反序列化会抛出你定义的异常:

    var foo = JsonConvert.DeserializeObject(
      @"{""NameRegex"":""abc+""}",
      typeof(Foo));
    

    **** NameRegex 值 '*abc+' 不是有效的正则表达式 ****

    【讨论】:

      【解决方案3】:

      JSON 模式有一个注释关键字 format,一些验证器也会验证(根据规范,这是可选的)。

      所以你可以说:

      {
          "type": "object",
          "properties": {
              "NameRegex": {
                  "type": "string",
                  "format": "regex"
              }
          }
      }
      

      但验证器不需要验证“格式”关键字。正如格雷格所提到的,即使您省略了* 前面的点,正则表达式通常仍然有效;它只是有不同的含义(重复星星前面的任何字符,而不是任何字符,零次或多次)

      尽管使用 format 关键字仍然是一个好主意,因为它至少可以很好地记录您对该属性的意图,即使您的特定验证器不验证格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 2021-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多