JSON (schema) 验证模式中的转义字符失败
JSON (schema) validation with escaped characters in patterns fails
以下JSON对象有效:
{
"foo": "bar",
"pattern": "^(\/?[-a-zA-Z0-9_.]+)+$"
}
而这个不是:
{
"foo": "bar",
"pattern": "^(\/?[-a-zA-Z0-9_.]+)+\.jpg$"
}
这是转义的 点 (\.
),但我不明白为什么这不应该有效 JSON。我需要在我的真实 JSON 模式中包含此类模式。那里的正则表达式要复杂得多,并且没有办法错过转义,尤其是点。
顺便说一句,在 字符 类 中转义 hypens 也会破坏验证。
我该如何解决?
编辑:我使用了 http://jsonlint.com 和几个节点库。
这里需要双重逃生。斜杠是 json 中的转义字符,因此您无法转义点(如它所见),而是需要转义该反斜杠,这样您的正则表达式就会像 \.
一样出现(json 在转义后需要一个保留字符,即引号或另一个斜线或其他东西)。
// passes validation
{
"foo": "bar",
"pattern": "^(/?[-a-zA-Z0-9_.]+)+\.jpg$"
}
您可以使用来自 ajv-keywords 的正则表达式
import Ajv from 'ajv';
import AjvKeywords from 'ajv-keywords';
// ajv-errors needed for errorMessage
import AjvErrors from 'ajv-errors';
const ajv = new Ajv.default({ allErrors: true });
AjvKeywords(ajv, "regexp");
AjvErrors(ajv);
// modification of regex by requiring Z https://www.regextester.com/97766
const ISO8601UTCRegex = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?Z$/;
const typeISO8601UTC = {
"type": "string",
"regexp": ISO8601UTCRegex.toString(),
"errorMessage": "must be string of format 1970-01-01T00:00:00Z. Got [=10=]",
};
const schema = {
type: "object",
properties: {
foo: { type: "number", minimum: 0 },
timestamp: typeISO8601UTC,
},
required: ["foo", "timestamp"],
additionalProperties: false,
};
const validate = ajv.compile(schema);
const data = { foo: 1, timestamp: "2020-01-11T20:28:00" }
if (validate(data)) {
console.log(JSON.stringify(data, null, 2));
} else {
console.log(JSON.stringify(validate.errors, null, 2));
}
以下JSON对象有效:
{
"foo": "bar",
"pattern": "^(\/?[-a-zA-Z0-9_.]+)+$"
}
而这个不是:
{
"foo": "bar",
"pattern": "^(\/?[-a-zA-Z0-9_.]+)+\.jpg$"
}
这是转义的 点 (\.
),但我不明白为什么这不应该有效 JSON。我需要在我的真实 JSON 模式中包含此类模式。那里的正则表达式要复杂得多,并且没有办法错过转义,尤其是点。
顺便说一句,在 字符 类 中转义 hypens 也会破坏验证。
我该如何解决?
编辑:我使用了 http://jsonlint.com 和几个节点库。
这里需要双重逃生。斜杠是 json 中的转义字符,因此您无法转义点(如它所见),而是需要转义该反斜杠,这样您的正则表达式就会像 \.
一样出现(json 在转义后需要一个保留字符,即引号或另一个斜线或其他东西)。
// passes validation
{
"foo": "bar",
"pattern": "^(/?[-a-zA-Z0-9_.]+)+\.jpg$"
}
您可以使用来自 ajv-keywords 的正则表达式
import Ajv from 'ajv';
import AjvKeywords from 'ajv-keywords';
// ajv-errors needed for errorMessage
import AjvErrors from 'ajv-errors';
const ajv = new Ajv.default({ allErrors: true });
AjvKeywords(ajv, "regexp");
AjvErrors(ajv);
// modification of regex by requiring Z https://www.regextester.com/97766
const ISO8601UTCRegex = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?Z$/;
const typeISO8601UTC = {
"type": "string",
"regexp": ISO8601UTCRegex.toString(),
"errorMessage": "must be string of format 1970-01-01T00:00:00Z. Got [=10=]",
};
const schema = {
type: "object",
properties: {
foo: { type: "number", minimum: 0 },
timestamp: typeISO8601UTC,
},
required: ["foo", "timestamp"],
additionalProperties: false,
};
const validate = ajv.compile(schema);
const data = { foo: 1, timestamp: "2020-01-11T20:28:00" }
if (validate(data)) {
console.log(JSON.stringify(data, null, 2));
} else {
console.log(JSON.stringify(validate.errors, null, 2));
}