简体   繁体   中英

How do I validate a string using a regular expression with Ajv?

I'm trying to validate a string(Phone number) with this regex ^+[0-9]{9,12}$

but I get this error ... .pattern should match format "regex"...

I've been through the documentation at https://ajv.js.org etc. looked at examples etc. and tried a lot of variations, but can't seem to figure out what is wrong with my code.

Here is my code:

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!');
}

Link to JSFiddle: http://jsfiddle.net/xnw2b9zL/4/ (Open Console / Debugger to see the full error)

TL; DR

Your regular expression is valid in a literal notation form but not in a constructor form where it is embedded into a string.

"\+""\\+"

When embedding a regular expression into a string, double check your escape characters!

Why?

Because useless escape characters will be ignored. If it wasn't for constructing a regular expression you have no reason to escape a '+' character:

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

The error you saw had nothing to do with the data, it was in the construction of the schema. As you can see here:

 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>

But digging deeper, it has nothing to do with Ajv either. Ajv does mention:

Ajv uses new RegExp(value) to create the regular expression that will be used to test data.

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

So what does it mean to do new RegExp("\+") ? Let's find out:

 // 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) }

Related

In addition to @customcommander comment.

The documentation about format state that:

regex: tests whether a string is a valid regular expression by passing it to RegExp constructor.


In javascript when you declare a string the backslashes will be interpreted. That's why you need to double the backslashes.

If you don't, what you are passing to Avg and in fine to new RegExp(...) is the string "^+[0-9]{9,12}$" , which is an incorrect RegExp.

在此处输入图像描述


PS: nice dog

Your regex is wrongly stringified. To avoid mistakes you can use native Regex as follow:

{
  type: 'string', 
  pattern: /^\+[0-9]{9,12}$/.toString()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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