JS RegEx .replace()条件模式&亚

时间:2013-02-14 11:09:38

标签: javascript regex

我需要格式化比利时电话号码。根据城市的不同,本地前缀长度为1或2个字符,我无法确定如何编写单个RegEx以匹配它们...

这是我迄今为止所做的,它有效,但它需要两个步骤:

2个字符前缀:

/(0{0,3}32)(93|92|89|87|86|85|84|83|82|81|80|71|69|67|65|64|63|62|61|60|59|58|57|56|55|54|53|52|51|50|28|26|25|22|19|16|15|14|13|12|11|10)([0-9]{2})([0-9]{2})([0-9]{2})/

1个字符前缀:

/(0{0,3}32)(9|8|7|6|5|4|3|2)([0-9]{3})([0-9]{2})([0-9]{2})/

模式:

"+$1 $2 $3 $4 $5"

我知道如何将两个RegEx组合在一起以及为.replace()使用相同的模式吗?

2 个答案:

答案 0 :(得分:2)

封装检查和格式化的自定义对象怎么样?

function BelgianPhoneNumber(inputStr) {
    var re = /0{0,3}32(?:(9[23]|8[0-79|7[1]|6[0-579]|5[0-9]|2[2568]|1[0-69])([0-9]{2})|([2-9])([0-9]{3}))([0-9]{2})([0-9]{2})/,
        match, area, grp1, grp2, grp3;

    if (match = re.exec(inputStr)) {
        if (match[1]) {
            area = match[1];
            grp1 = match[2];
        } else {
            area = match[3];
            grp1 = match[4];
        }
        grp3 = match[5];
        grp4 = match[6];
    } else {
        area = grp1 = grp2 = grp3 = "";
        // possibly throw error
    }

    this.toString = function () {
        if (match) {
            return ["+32", area, grp1, grp2, grp3].join(" ");
        } else {
            return "invalid phone number: " + inputStr;
        }
    }
}

用法

var p = new BelgianPhoneNumber("003233437667");
console.log("Phone: " + p);  // -> Phone: +32 3 343 76 67

var p = new BelgianPhoneNumber("003287565656")
console.log("Phone: " + p);  // -> Phone: +32 87 56 56 56

我不知道两个编号模式是否可以重叠,但是在匹配时会产生误报。

然而,当有疑问时,正则表达式支持2位数区域代码超过1位数区域代码。如果您想要反过来,请更改“选择...”组的顺序。

自定义对象的参数是您可以轻松添加.getAreaCode()等方法或将区号映射到城市名称的方法。而且,由于覆盖了.toString()方法,您仍然可以直接在字符串中使用它。

合并的正则表达式分解为

0{0,3}32               # constant prefix, therefore no group
(?:                    # choice: either...
  (9[23]|8[0-79|7[1]|6[0-579]|5[0-9]|2[2568]|1[0-69])   # 2-digit area code
  ([0-9]{2})                                            # first group (2 digits)
  |                                                     # or...
  ([2-9])                                               # 1-digit area code
  ([0-9]{3})                                            # first group (3 digits)
)                      # end choice
([0-9]{2})             # second group (2 digits)
([0-9]{2})             # third group (2 digits)

答案 1 :(得分:1)

您的第一个正则表达式可以简化为:

(0{0,3}32)(9[23]|8[0-79]|71|6[0-79]|5[0-9]|2[2568]|1[0-69])([0-9]{2})([0-9]{2})([0-9]{2})

你的第二个也可以简化为:

(0{0,3}32)([2-9])([0-9]{3})([0-9]{2})([0-9]{2})

这是结合这两个正则表达式的可能解决方案之一:

(0{0,3}32)(?:(9[23]|8[0-79]|71|6[0-79]|5[0-9]|2[2568]|1[0-69])([0-9]{2})|([2-9])([0-9]{3}))([0-9]{2})([0-9]{2})

您需要的每个群组仍然可以访问。尽管这些组的索引发生了变化。要检索您在问题中提供的格式,请将匹配的字符串替换为:

+$1 $2$4 $3$5 $6 $7

Demo