Есть ли функция, которая проверяет определенную длину?
Я пробовал .min(5) и .max(5), но мне нужно что-то, что гарантирует, что номер будет ровно 5 символов (например, почтовый индекс).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не думаю, что есть что-то встроенное, но это легко реализовать с помощью test:
yup.string()
.test('len', 'Must be exactly 5 characters', val => val.length === 5)
https://runkit.com/tamlyn/5ad9b99a4ba1230012d7ac21
Работает как часы. Большое спасибо. Мы также можем сделать это необязательным.
@Tamlyn Почему мы используем здесь string (). Test () // метод тестирования. Это тот метод, который следует использовать, или есть другой метод, который ему больше подходит? Почему-то .test () больше похож на метод тестирования ...
Но что с числами, у которых ведущее значение равно 0? 000123.toString (). Length //: выводит 3 (не 6)
@karolkarp Я не понимаю, о чем вы. Для начала 000123.toString().length выводит 2, а не 3. Это связано с тем, что синтаксический анализатор JavaScript интерпретирует числовые литералы, начинающиеся с нуля, как восьмеричные числа. Но в JavaScript нет внутреннего представления для числа с ведущими нулями. Если в начале есть нули, то это должна быть строка. И если вам не нужны ведущие нули в строке, нормализуйте ее parseFloat("000123").toString().length === 3.
Для справки в будущем, если вы хотите проверить номер (почтовый индекс), вышеуказанное решение требует небольшой настройки. Функция должна быть:
Yup.number().test('len', 'Must be exactly 5 characters', val => val.toString().length === 5)
.length не работает с числами, только со строками.
У меня было предупреждение о том, что val не определено. Я видел комментарий Мезе к первому ответу и решил, что должна быть нулевая проверка. Так, например, Yup.number().test('len', 'Must be exactly 5 characters', (val) => { if (val) return val.toString().length === 8; }).
Спасибо @Hylle. Это настоящий ответ!
Кроме того, по возможности не храните почтовые индексы в виде целых чисел. Почтовые индексы могут начинаться с 0 (на северо-востоке), что обрезает начальный ноль. Вероятно, лучше всего хранить как varchar.
@Tamlyn отвечать довольно хорошо охватывает аспект проверки длины вопроса.
В случае почтового индекса вы можете использовать регулярное выражение для обеспечения длины и ограничения числовых значений в Yup.string() (вы не захотите использовать тип Yup.number(), поскольку он не будет поддерживать почтовые индексы, начинающиеся с нуля 0####)
// ##### format zip code
Yup.string().matches(/^[0-9]{5}$/, 'Must be exactly 5 digits')
// ##### and #####-#### format zip codes
Yup.string().matches(/^[0-9]{5}(?:-[0-9]{4})?$/, 'Must be 5 or 9 digits')
Привет, дтеста! Спасибо за ваше решение. Ваш код: Yup.string (). Соответствует (/ ^ [0-9] {5} $ /, 'Должно быть ровно 5 цифр') работает, но мне также нужно проверить минимум и максимум, так что я сделал был для пользователя .min (10, «Должно быть ровно 10–12 цифр.») и .max (12, «Должно быть ровно 10–12 цифр.»).
Чтобы добавить к другим ответам, никто из них не проверяет, существует ли значение (я вижу, что некоторые упомянули об этом в комментариях после публикации этого) ...
Если его нет и поле оставлено пустым, он будет пытаться получить длину undefined или null, что затем выдаст вам ошибку javascript и предотвратит работу других условий, таких как .required() (если вы настроили его, как, конечно, ).
Вероятно, это было бы немного лучше:
// Check we have a value as well
Yup.number().test('len', 'Must be exactly 5 characters', val => val && val.toString().length === 5 )
Использование number() не работает, поскольку вы можете ввести защитный код, который начинается с нулей, а Yup.number () их проглатывает. Пример: 000445 будет передан в val как 445.
Вы также можете использовать string.length.
yup.string().length(5)
Но не работает с числами, начинающимися с нуля:
const yup = require('yup')
const schema = yup.string().length(5)
console.info(schema.isValidSync(12345)) // (true) This is valid.
console.info(schema.isValidSync(00123)) // (false) This is NOT valid.
@ mirind4 Это то, о чем он просит, необходимая длина.
Ах, да, я действительно неправильно понял контекст, извините. Удаляю свой комментарий, и мне нравится ваш ответ!
Это то, что я искал. Если вам нужно улучшить сообщение об ошибке, yup.string().length(5, "Should be exactly 5 chars")
отвечать @ efru отлично подходит для чисел, длина которых меньше 22 символов. Однако val.toString().length не работает с числами, длина которых превышает 22 символа. Причина этого в том, что большие числа преобразуются в экспоненциальный формат при преобразовании в строку в javascript.
Лучше всего работает следующее решение:
Yup.number().test('len', 'Must be exactly 25 characters', val => Math.ceil(Math.log10(val + 1)) === 25)
Эта проверка приводит к лучшему опыту проверки:
Yup.string()
.required()
.matches(/^[0-9]+$/, "Must be only digits")
.min(5, 'Must be exactly 5 digits')
.max(5, 'Must be exactly 5 digits')
выход:
12f1 // Must be only digits
123 // Must be exactly 5 digits
123456 // Must be exactly 5 digits
01234 // valid
11106 // valid
Демо: https://codesandbox.io/s/yup-y6uph
Ваше состояние будет неудачным, если zip начнется с 0, например: 08763
@InamurRahman Мой пример уже включает строку цифр с нулевым префиксом, которая проходит проверку, как показано в демонстрации. Помните, что мы проверяем строки. Вы не можете сохранить начальный ноль в числовом значении. это невозможно ни на одном языке программирования. console.info(08763) будет выводить > 8763, но console.info('08763') выводит > 08763
Я тестировал его с "00000" и работает как шарм. Мне понравилось это решение, спасибо @SimoAmi
Я люблю тебя, брат, за это решение
Тестовый API сталкивается с проблемами с ReactJs, когда ваше поле не имеет значения. Вместо этого вы можете использовать API длины
Yup.string().length(4, 'This field has to be exactly 4 characters!')
Ваш путь правильный и самый простой.
Yup.string()
.required()
.min(5, 'Must be exactly 5 digits')
.max(5, 'Must be exactly 5 digits')
import { string, date} from 'yup' // Take out what is needed in import
string()
.trim()
.matches(
/^[0-9]{4}[0-9]{2}[0-9]{2}T 0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$/,
'createdOn is not in correct format',
)
.max(24),
Привет! Хотя этот код может решить вопрос, включая объяснение о том, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, приведет к большему количеству голосов за. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас. Пожалуйста, редактировать свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются.
Попробуй это:
Yup.number()
.required()
.min(10000, 'Must be exactly 5 characters')
.max(99999, 'Must be exactly 5 characters')
.label("Zip Code"),
Этот ответ подчеркивает тот факт, что min и max по-разному работают для string () и number ().
Это не работает. А как насчет почтовых индексов, начинающихся с 0? Вы не можете сделать поле почтового индекса числом или проверить, что оно находится между двумя числами.
Вы также можете использовать проверку для числа, но при использовании теста для проверки длины вы должны преобразовать его в строку, прежде чем проверять ее.
Yup.object().shape({
zipCode: Yup.number()
.required('Zip code is a required field')// optional
.typeError('Zip code can only be a number')// optional as well
.test('len', 'Zip code needs to be excatly 5 digits', val => val.toString().length === 5)
});
Работает как амулет для типа числа.
yup.number().test('len', 'Max 6 numbers', (val) => val.toString().length <= 6)
Мне пришлось добавить нулевую проверку, так как вполне возможно, что строка val имеет значение null, потому что пользователь еще ничего не набрал