如何使用带有 Ajv 的正则表达式验证字符串?

Posted

技术标签:

【中文标题】如何使用带有 Ajv 的正则表达式验证字符串?【英文标题】:How do I validate a string using a regular expression with Ajv? 【发布时间】:2020-09-24 21:17:36 【问题描述】:

我正在尝试使用此正则表达式验证字符串(电话号码)^+[0-9]9,12$

但我收到此错误 ... .pattern should match format "regex" ...

我浏览了https://ajv.js.org 等处的文档。查看了示例等并尝试了很多变体,但似乎无法弄清楚我的代码有什么问题。

这是我的代码:

const schema = 
    type: 'object',
    properties: 
        users: 
            type: 'array',
            items: 
                type: 'object',
                properties: 
                    userReference:  type: 'string' ,
                    phone: 
                        type: 'string'
                        , pattern: "^\+[0-9]9,12$" // If I remove this line, the model is seen as valid (and no errors)
                    
                
            
        
    ,
    required: ['users'],
    errorMessage:  _: "One or more of the fields in the 'legacy' data path are incorrect." 
;

const schemaSample = 
    "users": [
        
            "phone": "+25512345678", // should be valid
            "userReference": "AAA"
        ,
        
            "phone": "+5255 abc 12345678", // should be invalid
            "userReference": "BBB"
        
    ]
;

var ajv = Ajv();
ajv.addSchema(schema, 'schema');

var valid = ajv.validate('schema', schemaSample);
if (valid) 
    console.log('Model is valid!');
 else 
    console.log('Model is invalid!');


链接到 JSFiddle:http://jsfiddle.net/xnw2b9zL/4/(打开控制台/调试器查看完整错误)

【问题讨论】:

你很可能忘记了双重转义:"\+" 应该是 "\\+" 我真的在这该死的东西上花了好几个小时!!谢谢那成功了。如果您将其发布为答案,我会将其标记为正确,否则我将稍后回答我自己的问题。 【参考方案1】:

TL;博士

您的正则表达式 在文字符号形式中有效,但在嵌入字符串的构造函数形式中无效。

"\+""\\+"

将正则表达式嵌入字符串时,请仔细检查转义字符!

为什么?

因为无用的转义字符会被忽略。如果不是为了构造正则表达式,您没有理由转义 '+' 字符:

"\+" === "+"
//=> true

您看到的错误与数据无关,它与架构的构造有关。正如你在这里看到的:

const ajv = new Ajv;

try 
  ajv.compile(type: 'string' , pattern: '^\+[0-9]9,12$');
 catch (e) 
  console.log(`ERR! $e.message`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>

但深入挖掘,它也与 Ajv 无关。 Ajv 确实提到:

Ajv 使用 new RegExp(value) 创建将用于测试数据的正则表达式。

见https://ajv.js.org/keywords.html#pattern

那么new RegExp("\+") 是什么意思呢?让我们找出答案:

// similar error because "\+" and "+" are the same string
try  new RegExp("\+")  catch (e)  console.log(e.message) 
try  new RegExp("+")  catch (e)  console.log(e.message) 

相关

Why do linters pick on useless escape character?

【讨论】:

【参考方案2】:

除了@customcommander 评论。

关于format 的文档指出:

regex:通过传递来测试一个字符串是否是一个有效的正则表达式 它到 RegExp 构造函数。


javascript 中,当您声明一个字符串时,反斜杠将被解释。这就是为什么您需要将反斜杠加倍。

如果你不这样做,你传递给 Avg 和 new RegExp(...) 的内容是字符串 "^+[0-9]9,12$",这是一个不正确的正则表达式。


PS:好狗

【讨论】:

我认为我的正则表达式格式正确,因为我将它输入到 regex101 并为其生成了 javascript,它生成了 /^\+[0-9]9,12$/gm,但是我现在看到它不是在字符串中生成的。所以从没想过仔细检查我的正则表达式。

以上是关于如何使用带有 Ajv 的正则表达式验证字符串?的主要内容,如果未能解决你的问题,请参考以下文章

带有逗号分隔符的数字的正则表达式验证

手机号码的正则表达式,带有某些条件的电话号码验证

如何在 ruby​​ 中使用 utf8 的正则表达式

js如何正则验证密码

如何使用 java 正则表达式验证字符串?

如何使用正则表达式验证逗号分隔的字符串 [重复]