Как проверить строку с помощью регулярного выражения с помощью Ajv?

Я пытаюсь проверить строку (номер телефона) с помощью этого регулярного выражения ^+[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/ (открытая консоль/отладчик чтобы увидеть полную ошибку)


person LegionDev    schedule 05.06.2020    source источник
comment
Вы, скорее всего, забыли двойной escape: "\+" должно быть "\\+"   -  person customcommander    schedule 05.06.2020
comment
Я буквально потратил ЧАСЫ на эту чертову штуку!! Спасибо, это сработало. Если вы опубликуете это как ответ, я отмечу его как правильный, иначе я отвечу на свой вопрос позже.   -  person LegionDev    schedule 05.06.2020


Ответы (2)


TL; DR

Ваше регулярное выражение допустимо в буквальной форме записи, но не в форме конструктора, где оно встроено в строку.

"\+""\\+"

При встраивании регулярного выражения в строку дважды проверяйте escape-символы!

Почему?

Потому что бесполезные escape-символы будут игнорироваться. Если бы не построение регулярного выражения, у вас не было бы причин экранировать символ '+':

"\+" === "+"
//=> 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 использует новое регулярное выражение (значение) для создания регулярного выражения, которое будет использоваться для проверки данных.

См. 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) }

Связанные

person customcommander    schedule 05.06.2020

В дополнение к комментарию @customcommander.

В документации по формату указано следующее:

регулярное выражение: проверяет, является ли строка допустимым регулярным выражением, передавая ее конструктору RegExp.


В javascript, когда вы объявляете строку, обратная косая черта будет интерпретироваться. Вот почему вам нужно удвоить обратную косую черту.

Если вы этого не сделаете, вы передаете в Avg и, наконец, в new RegExp(...) строку "^+[0-9]{9,12}$", которая является неправильным RegExp.

введите здесь описание изображения


ПС: хорошая собака

person Orelsanpls    schedule 05.06.2020
comment
Я думал, что мое регулярное выражение отформатировано правильно, так как я ввел его в regex101 и сгенерировал для него javascript, и он сгенерировал /^\+[0-9]{9,12}$/gm, но теперь я вижу, что он не сгенерирован в нить. Поэтому никогда не думал дважды проверять мое регулярное выражение. - person LegionDev; 05.06.2020