vee-validate正则表达式无法工作

6
我需要使用vee-validate验证美国电话号码XXX-XXX-XXXX,使用此基本正则表达式(?:\d{3}-)\d{3}-\d{4}。 正则表达式单独使用效果良好,但与vee-validate一起使用时无法正常工作,我不确定原因。
<!DOCTYPE html>
<html>
   <head>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/vee-validate@latest/dist/vee-validate.js"></script>
   </head>
   <body>
      <div id="app">
         <form action='#' method='POST'>

            <input v-validate="'required|regex:^(?:\(\d{3}\)|\d{3}-)\d{3}-\d{4}$'" :class="{'input': true, 'is-danger': errors.has('phone_primary') }" class="input is-info" type="text" name='phone_primary' value="$phone_primary" placeholder="404-555-1212" size="15">
            <span v-show="errors.has('phone_primary')" class="help is-danger">{{ errors.first('phone_primary') }}</span>

            <button class="button is-link" name='submitform' value='go'>Submit</button>
         </form>
      </div>
      <script>
         Vue.use(VeeValidate);
         new Vue({
           el: '#app',
           template: '#app',
           data: {
              phone_primary: null
           }
         });
      </script>

    </body>
</html>

Fiddle

我做错了什么,导致正则表达式没有按照预期工作?

2个回答

12
v-validate指令接受由管道符(|)分隔的验证列表字符串值。由于管道符在正则表达式模式中也被用作替换运算符,因此该字符串命令会失效。为了解决这个问题,应传递一个对象而不是字符串值。
此外,在vee-validate中的正则表达式需要使用正则表达式定界符,即模式周围的/字符。
因此,您可以使用:
v-validate="{ required: true, regex:/^(?:\(\d{3}\)|\d{3}-)\d{3}-\d{4}$/ }"

请查看更新的fiddle示例

请注意,正则表达式不匹配空字符串,因此空输入将无效。

另外,如果您在某个不允许传递对象的组件中使用它,请使用自定义规则:

Vue.use(VeeValidate);

new Vue({
  el: '#app',
  created() {
    this.$validator.extend('phone_pattern', {
      getMessage(field, val) {
        return 'The ' + field + ' field should match the "(XXX)XXX-XXX-XXXX" or "123-XXX-XXXX" pattern!'
      },
      validate(value, field) {
        return /^(?:\(\d{3}\)|\d{3}-)\d{3}-\d{4}$/.test(value);
      }
    })
  },
  methods: {
    validate() {
      this.$validator.validateAll()
        .then((result) => {
          if (result) {
            alert('valid!');
          }
        });
    }
  }
});
.text-danger {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vee-validate/2.0.9/vee-validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <form action="" @submit.prevent="validate">
    <div class="form-group">
      <label for="">Phone number:</label>
      <input name="phone" type="text" class="form-control" v-validate="'required|phone_pattern'" />
      <span class="text-danger">{{ errors.first('phone') }}</span>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
</div>


当我留空字段时,无法触发验证错误。 - a coder
完美,现在运行得很好。在所有输入中使用花括号而不是单引号有什么好处吗?目前正在使用后者。 - a coder
1
@acoder 我认为问题出在 | 字符上:因为你在正则表达式模式中使用它(作为交替运算符),而纯字符串命令就无效了。在 PHP Laravel 中也观察到了类似的问题,解决方法也是相同的:只需使用选项数组即可。v-validate 指令接受一个字符串值,其中包含用管道 (|) 分隔的验证列表。 由于管道也被用作正则表达式模式中的交替运算符,所以字符串命令就无效了。我在答案中添加了更多细节。 - Wiktor Stribiżew

1
我在使用内置的v-validate规则时,遇到了使用复杂正则表达式的问题。我有一个正则表达式,用于检查密码字段是否同时包含字母和数字。该正则表达式为:/^(?=.[0-9])(?=.[a-zA-Z])([a-zA-Z0-9]+)$/g。
我花费了很长时间尝试使用内置的regex参数来解决这个问题,但是没有成功。最终,我编写了自己的扩展程序。因此,在我的mounted函数中:
this.$validator.extend('complex_password', {
   validate(value, args) {
   return Util.isComplexPassword(value);
   }
})

然后我在我的工具库中添加了一个函数:

 isComplexPassword(value) {
    
        tester = /^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$/g
        isMatch = !tester.test(String(value))
    
        return !isMatch
    },

最后,将其钩入我的字段验证中:
v-validate="'required|min:8|complex_password'"


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