使用Yup进行验证以检查字符串或数字长度

98

是否有一个名为yup的函数可以验证特定长度?

我尝试过.min(5).max(5),但我需要确保数字正好是5个字符长度(例如邮政编码)的一些东西。

17个回答

101

这个检查可以带来最佳的验证体验:

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


@InamurRahman 我的示例已经包括了一个以零为前缀的数字字符串,它通过了演示中所示的验证。请记住,我们正在验证字符串。您无法在数值中保留前导零。这在任何编程语言中都是不可能的。console.log(08763)将输出> 8763,但console.log('08763')将输出> 08763 - SimoAmi
1
我用“00000”进行了测试,效果非常好。喜欢这个解决方案,谢谢@SimoAmi。 - Manjar
1
我爱你兄弟为这个解决方案。 - Agent K
值应该恰好为5,而不是输入值的长度? - Mustkeem K
在字符串的上下文中,min和max指的是输入字符串的长度。 - SimoAmi

86

6
我不得不添加一个空值检查器,因为用户可能还没有输入任何内容,导致val字符串为空。 - Mese
它运行得非常好。非常感谢。我们还可以将其设置为非必需的。 - Nagama Inamdar
@Tamlyn 为什么我们要使用 string().test() // 在这里使用测试方法? 这是应该使用的方法,还是有另一种更适合的方法? 不知何故,.test() 更像是一个测试方法... - Roxy'Pro
3
如果数字的开头是0,该怎么办?例如:000123.toString().length // 输出3(而不是6) - karolkarp
1
@karolkarp 我不明白你的意思。首先,000123.toString().length 的输出是 2 而不是 3。这是因为 JavaScript 解析器将以零开头的数字字面量解释为八进制数。但是,JavaScript 没有带前导零的数字的内部表示。如果它有前导零,则必须是一个字符串。如果您不想在字符串上有前导零,请将其规范化为 parseFloat("000123").toString().length === 3 - Tamlyn

39

为了以后的参考,如果您想验证一个数字(邮政编码),上述解决方案需要稍微修改。该函数应改为:

Yup.number().test('len', '必须是5个字符', val => val.toString().length === 5)

.length不适用于数字,只适用于字符串。


3
我收到一个关于val未定义的警告。我看到Mese在第一个答案中的评论,认为应该进行空值检查。因此,例如可以使用Yup.number().test('len', '必须正好是5个字符', (val) => { if(val) return val.toString().length === 8; }) - Hylle
1
谢谢@Hylle。这才是真正的答案! - Ahmed Aziz
另外,如果可能的话,请勿将邮政编码存储为整数。邮政编码可能以0开头(在东北部),这将截断前导零。最好将其存储为varchar。 - efru
1
在一行代码中补偿空值或 null:val && val => val.toString().length === 5 - Jake
将邮政编码存储为字符串,而不是数字。邮政编码有时以零开头(例如纽约),如果存储为整数,则会截断前导零。 - efru

28

您还可以使用string.length

yup.string().length(5)

但是它不能处理以零开头的数字:

const yup = require('yup')

const schema = yup.string().length(5)

console.log(schema.isValidSync(12345)) // (true) This is valid.
console.log(schema.isValidSync(00123)) // (false) This is NOT valid.

@mirind4 这就是他所要求的,需要的长度。 - David Ferreira
啊,对了,我确实误解了上下文,抱歉。我删除我的评论,我喜欢你的回答! - mirind4
1
这正是我在寻找的。如果您需要改进错误消息,可以使用 yup.string().length(5, "应该恰好为5个字符") - benftwc

17

@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')

嗨dtesta!感谢您的解决方案。您的代码是:Yup.string().matches(/^[0-9]{5}$/, '必须正好为5位数字'),它可以工作,但我还需要检查最小和最大值,所以我使用了.min(10, '必须正好为10-12位数字。')和.max(12, '必须正好为10-12位数字。')。 - Jeanne vie

9

对于数字类型,它的效果非常好。

yup.number().test('len', 'Max 6 numbers', (val) => val.toString().length <= 6)

6

除了其他答案外,它们都没有检查是否存在某个值(尽管发布后我看到有些人在评论中提到了这一点)...

如果它不存在且该字段为空,则将尝试获取undefinednull的长度,这将导致javascript错误并防止其他条件(如果你当然设置了.required())起作用。

这可能会稍微好一些:

// Check we have a value as well
Yup.number().test('len', 'Must be exactly 5 characters', val => val && val.toString().length === 5 )

1
使用 number() 不起作用,因为您可能正在输入以零开头的安全代码,而 Yup.number() 会将它们吞噬掉。例如:000445 将被传递给 val 作为 445 - SimoAmi

5

尝试这个:

Yup.number()
.required()
.min(10000, 'Must be exactly 5 characters')
.max(99999, 'Must be exactly 5 characters')
.label("Zip Code"),

1
这个答案强调了min和max在string()和number()中的不同工作方式。 - technoY2K
7
这个不起作用。那么以“0”开头的邮政编码怎么办?你不能将邮政编码字段设置为数字,也无法验证它是否在两个数字之间。 - Mike

3

您仍然可以使用验证数字的方法,但如果要验证长度,您需要在测试之前将其转换为字符串。

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

2

当您的字段没有值时,测试API在ReactJs中遇到问题。您可以改用长度API。

Yup.string().length(4, 'This field has to be exactly 4 characters!')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接