【问题标题】:Validation using Yup to check string or number length使用 Yup 进行验证以检查字符串或数字长度
【发布时间】:2022-03-17 04:45:24
【问题描述】:

是否有验证特定长度的 yup 函数?

我尝试了.min(5).max(5),但我想要确保数字正好是5 个字符(即邮政编码)的东西。

【问题讨论】:

    标签: javascript reactjs formik yup


    【解决方案1】:

    我认为没有内置任何东西,但使用test 很容易实现:

    yup.string()
      .test('len', 'Must be exactly 5 characters', val => val.length === 5)
    

    https://runkit.com/tamlyn/5ad9b99a4ba1230012d7ac21

    【讨论】:

    • 我必须添加一个空检查器,因为 val 字符串可能是空的,因为用户还没有输入任何内容
    • 它就像一个魅力。非常感谢。我们也可以让它不是必需的。
    • @Tamlyn 为什么我们在这里使用 string().test() // 测试方法是应该使用的方法还是有其他更适合的方法?不知何故 .test() 听起来更像是一种测试方法...
    • 但是前导为 0 的数字呢? 000123.toString().length // : 输出 3(不是 6)
    • @karolkarp 我不明白你的意思。首先000123.toString().length 输出2,而不是3。这是因为 JavaScript 解析器将从零开始的数字文字解释为八进制数。但是 JavaScript 没有内部表示带有前导零的数字。如果它有前导零,那么它必须是一个字符串。如果您不想在字符串中出现前导零,请将其标准化parseFloat("000123").toString().length === 3
    【解决方案2】:

    此检查可带来最佳验证体验:

    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 我的示例已经包含一个前缀为 0 的数字字符串,它通过了验证,如演示中所示。请记住,我们正在验证字符串。您不能在数值中保留前导零。这在任何编程语言中都是不可能的。 console.log(08763) 将输出 > 8763console.log('08763') 将输出 > 08763
    • 我用“00000”对其进行了测试,效果很好。喜欢这个解决方案,谢谢@SimoAmi
    • 我爱你这个解决方案的兄弟
    【解决方案3】:

    为了将来参考,如果您要验证数字(邮政编码),上述解决方案需要稍作调整。函数应该是:

    Yup.number().test('len', 'Must be exactly 5 characters', val => val.toString().length === 5)

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

    【讨论】:

    • 我收到关于 val 未定义的警告。我看到了 Mese 对第一个答案的评论,并认为应该有一个空检查。以Yup.number().test('len', 'Must be exactly 5 characters', (val) => { if(val) return val.toString().length === 8; }) 为例。
    • 谢谢@Hylle。这才是真正的答案!
    • 另外,如果可以的话,不要将邮政编码存储为整数。邮政编码可以以 0 开头(在东北部),这将切断前导零。可能最好存储为 varchar。
    • 补偿1行中的空或null:val && val => val.toString().length === 5
    【解决方案4】:

    您也可以使用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 这就是他要求的,需要的长度。
    • 啊,对,我确实误解了上下文,对不起。我删除了我的评论,我喜欢你的回答!
    • 这就是我想要的。如果需要改进错误信息,yup.string().length(5, "Should be exactly 5 chars")
    【解决方案5】:

    @Tamlyn 的answer 很好地涵盖了问题的长度验证方面。

    在邮政编码的情况下,您可以使用regex 来强制限制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}$/, 'Must is just 5 digits') 有效,但我还需要检查最小值和最大值,所以我做了什么是给用户 .min(10, '必须是 10-12 位数字。') 和 .max(12, '必须是 10-12 位数字。')。
    【解决方案6】:

    要添加到其他答案,他们都没有检查值是否存在(我看到有些人在发布后在 cmets 中提到了这一点)......

    如果它不存在并且该字段为空,它将尝试获取 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 )
    

    【讨论】:

    • 使用number() 不起作用,因为您可能输入了一个以零开头的安全代码,而 Yup.number() 会吞下它们。示例:000445 将作为445 传递给val
    【解决方案7】:

    就像类型号的魅力。

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

    【讨论】:

      【解决方案8】:

      试试这个:

      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 开头的邮政编码呢?您不能将邮政编码字段设为数字,也不能验证它是否介于两个数字之间。
      【解决方案9】:

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

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

      【讨论】:

        【解决方案10】:

        您仍然可以使用数字验证,但是当使用测试验证长度时,您需要在测试之前将其转换为字符串。

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

        【讨论】:

          【解决方案11】:

          @efru 的answer 适用于少于 22 个字符的数字。但是val.toString().length 不适用于大于 22 个字符的数字。原因是较大的数字在 javascript 中转换为字符串时会转换为指数格式。

          我发现效果最好的解决方案是:

          Yup.number().test('len', '必须正好是 25 个字符', val => Math.ceil(Math.log10(val + 1)) === 25)

          【讨论】:

            【解决方案12】:
            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),
            

            【讨论】:

            • 您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
            【解决方案13】:

            matches(/^[0-9]{8}$/, "Only 8 digits") 现在,如果用户输入字母和更多或更少的 8 位数字,Yup 将显示错误

            【讨论】:

              【解决方案14】:

              你的方法是正确的,也是最简单的。

              Yup.string()
              .required()
              .min(5, 'Must be exactly 5 digits')
              .max(5, 'Must be exactly 5 digits')
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2018-03-07
                • 1970-01-01
                • 1970-01-01
                • 2021-06-27
                • 1970-01-01
                • 2015-06-23
                • 2014-03-03
                相关资源
                最近更新 更多