如何使用一个输入控件应用多个ng-pattern

时间:2015-07-15 18:31:46

标签: angularjs

我正在尝试使用Angularjs在文本框中验证邮政编码和电话号码。但它不起作用

 <input type="text" class="form-control errorfields" id="postalCode"
 name="postalCode" ng-model="postalCode" 
 ng-pattern="/(^(\d{5}(-\d{4})?|[A-CEGHJ-NPRSTVXY]\d[A-CEGHJ-NPRSTV-Z]
  ?\d[A-CEGHJ-NPRSTV-Z]\d)$)||(^[0-9])/"  required>

3 个答案:

答案 0 :(得分:3)

首先,正如mico指出的那样,在你的正则表达式语法中使用双重管道是无效的,并且会破坏你的表达。

其次,ng-pattern只能验证每个输入的一个模式。如果您需要它来验证或者,您需要选择两个路由之一,创建自定义指令,或者向控制器添加一些逻辑以确定我们应该检查哪个表达式并使用数据绑定将其传递给ng-pattern。这在角度世界中是不好的做法,所以最好的办法就是做出指示。

答案 1 :(得分:1)

你的正则表达式有两个||而不是单一,这打破了正则表达式验证条款。

我把它粘贴到(https://regex101.com)并且它说char打破它。

答案 2 :(得分:1)

编辑: 这仅适用于以^和结尾$元字符开头的正则表达式。

就像我的许多StackOverflow答案一样,我迟到了这个聚会。这个问题使我步入正轨,但给出的答案都不足以做出最终解决方案。

这是我最近在阅读此线程后写的东西,未能完全回答我的问题,这使我的代码审阅者惊叹道:“这是WTF吗?随后他按下“合并”按钮。

我的问题是我有一个表单输入,我想接受它并针对纬度或经度正则表达式进行验证。我想与DMS,DDM和DD样式输入匹配。我本可以编写一个巨型表达式,但是我还需要在组件级别测试输入,以确定用户输入的类型并将其转换为DD。 lat / long的表达会使这个答案更加复杂,因此我使用的是我认为原始作者的意图。

如果您对经/纬度表达式感兴趣,请遵循以下要点:https://gist.github.com/pjobson/8f44ea79d1852900457bc257a4c9fcd5

这是对本次练习的代码的一种重写,我从有角度的地方对其进行了抽象,以使其更易于访问,因为它可以用于其他目的。

您似乎正在接受:北美邮政编码或英国邮政编码或以0-9开头的内容。

稍微充实一下正则表达式,我自己没有对它们进行很好的测试,因此您的里程可能会有所不同。在我看来,这就是需求的样子,它只是示例代码,因此3年后的时间并不重要。

 N.America Zip or Zip+4 (from sample above)
     ^(\d{5}(-\d{4})?$
 UK Zip Code (from wikipedia)
     ^([A-Za-z][A-Ha-hJ-Yj-y]?[0-9][A-Za-z0-9]? ?[0-9][A-Za-z]{2}|[Gg][Ii][Rr] ?0[Aa]{2})$
 N.America Phone Number (from RegExLib.com)
    ^[2-9]\d{2}-\d{3}-\d{4}$
 UK Phone Number (from RegExLib.com)
    ^(\s*\(?0\d{4}\)?\s*\d{6}\s*)|(\s*\(?0\d{3}\)?\s*\d{3}\s*\d{4}\s*)$

在一个对象中...

const expressions = {
    naZip: /^\d{5}(-\d{4})?$/,
    ukZip: /^([A-Za-z][A-Ha-hJ-Yj-y]?[0-9][A-Za-z0-9]? ?[0-9][A-Za-z]{2}|[Gg][Ii][Rr] ?0[Aa]{2})$/,
    naPhone: /^[2-9]\d{2}-\d{3}-\d{4}$/,
    ukPhone: /^(\s*\(?0\d{4}\)?\s*\d{6}\s*)|(\s*\(?0\d{3}\)?\s*\d{3}\s*\d{4}\s*)$/
 };

现在的问题是ng模式仅接受一个正则表达式,但是我有四个。我希望将这些内容保留为四种不同的内容,因此在我的组件中,我可以进行测试以找出用户输入的内容并根据其内容执行不同的操作。

这看起来像垃圾,但是效果很好。

 const combinedExpression = new RegExp(`^(${_.map(expressions, exp => `(${exp.toString().replace(/^\/\^(.+?)\$\/$/,'$1')})`).join('|')})$`);

当然,您可以从这里将其添加到模型中,然后将ng-pattern设置为模型。

我将在这里尝试以几种不同的方式对此进行解释...

这里是它的功能细分。

 new RegExp(`^(${_.map(expressions, exp => `(${exp.toString().replace(/^\/\^(.+?)\$\//g,'$1')})`).join('|')})$`);
 ^          ^^^^ ^                  ^      ^ ^ ^              ^                                ^  ^          ^^
 |          |||| |                  |      | | |              |                                |  |          ||
 |          |||| |                  |      | | |              |                                |  |          |+- end of the 1st template literal
 |          |||| |                  |      | | |              |                                |  |          +- end the expression with $
 |          |||| |                  |      | | |              |                                |  +- join all stringified expressions with a pipe so (a|b|c|d)
 |          |||| |                  |      | | |              |                                +- end of 2nd template literal
 |          |||| |                  |      | | |              +- replace the like /^(\d{5}(-\d{4})?$/ to (\d{5}(-\d{4})?
 |          |||| |                  |      | | +- convert the expression to a string
 |          |||| |                  |      | +- new Expression interpolation
 |          |||| |                  |      +- 2nd templte literal
 |          |||| |                  +- each expression is represented by exp
 |          |||| +- Using lodash map the expressions
 |          |||+- Expression interpolation
 |          ||+- Regex group match, we will be grouping each of the expressions
 |          |+- Regex starts with ^
 |          +- Starting a new template literal
 +- Establish a new combined expression.

进一步澄清...

我正在做的是获取每个表达式,将它们转换为字符串,删除起始结束字符,将它们作为OR组重新组合在一起,然后将整个内容转换为一个巨大的组合正则表达式。

进一步澄清...

如果那太令人困惑,那我可以看得出来...

  1. 遍历每个表达式。
  2. 将这些值中的每一个转换为字符串,以除去起始和结束部分,以便/^(\d{5}(-\d{4})?$/转换为(\d{5}(-\d{4})?
  3. 将所有这些都组合成一个大的OR组,这样您将得到类似(a|b|c|d)的信息,其中a, b, c, d是每个字符串化表达式。
  4. 以“ ^开始,以$结尾的OR组。
  5. new RegExp包裹整个内容。

用长篇JS进一步说明。

// Instantiate a new empty array
const strings = [];
// Loop the expressions
for (let key in expressions) {
  // Console log to see what we're getting
  console.log('original expression', expressions[key]);
  // assign the current expression
  let stringifiedExp = expressions[key];
  // convert the current expression to a string
      stringifiedExp = stringifiedExp.toString();
  // replace the starting /^ and ending $/ with the contents
      stringifiedExp = stringifiedExp.replace(/^\/\^(.+?)\$\/$/,'$1');
  // Console log to see what we got.
  console.log('stringified expression', stringifiedExp);
  // Push the stringified expression to strings.
  strings.push(stringifiedExp);
}

// Instantiate a new string which we'll build the regex with
let expString  = '^(';
    expString += strings.join('|');
    expString += ')$';

// Console log to see what we've got.
console.log(expString);

// Make a new Regular Expression out of the string
const combinedExpression = new RegExp(expString);

// Console log what we've got
console.log(combinedExpression);