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 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: / (Open Console / Debugger to see the full error)
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)
Share Improve this question edited Jun 12, 2020 at 21:16 customcommander 18.9k5 gold badges67 silver badges93 bronze badges asked Jun 5, 2020 at 15:43 LegionDevLegionDev 1,4714 gold badges18 silver badges29 bronze badges 2 |3 Answers
Reset to default 12TL; 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
- Why do linters pick on useless escape character?
Your regex is wrongly stringified. To avoid mistakes you can use native Regex as follow:
{
type: 'string',
pattern: /^\+[0-9]{9,12}$/.toString().slice(1, -1)
}
Note that .slice(1, -1)
removes the first and last characters which are the regexp delimiters and should not be included in the RegExp
constructor.
/test/.toString() // "/test/"
/test/.toString().slice(1, -1) // "test"
new RegExp(/test/.toString().slice(1, -1)) // /test/
You also cannot use any flag as they have to be provided as a separate argument to the RegExp constructor.
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
"\+"
should be"\\+"
– customcommander Commented Jun 5, 2020 at 15:47