JS RegEx .replace()条件模式和子组

问题描述:

我需要格式化比利时电话号码。根据不同的城市,当地的前缀是1或2个字符长,我想不出如何写一个正则表达式匹配他们... ...JS RegEx .replace()条件模式和子组

这里就是我这么远,它的工作原理的,但它需要两个步骤:

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" 

任何想法如何,我可以将二者结合起来的正则表达式,以及使用相同的模式进行.replace()?

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

(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

+1

为什么不干脆让不必要的群体为'非capturing'?这不会改变匹配的字符串。 – 2013-02-14 11:29:35

+0

@RohitJain如果我很好地理解输入/输出,则使用每个组。你在说什么非必要的团体? – sp00m 2013-02-14 11:31:47

+0

我的意思是你创建的外部组合这些正则表达式。像这样: - /(0 {0,3} 32)(?:(?:(9 [23] | 8 [0-79] | 71 | 6 [0-579] | 5 [0-9] | 2 [25-68] | 1 [0-69])([0-9] {2}))|(?:([2-9])([0-9] {3})))([0-9] {2})([0-9] {2})/' – 2013-02-14 11:33:40

如何封装检查自定义对象和格式化?

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 

我不知道这两个编号的模式是否能重叠,但是,当匹配产生误报。

然而,有疑问时,正则表达式有利于经1位数那些2位区号。如果您想反其道而行,请更改“选择...”组的顺序。

自定义对象的说法是,你可以轻松地添加像.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) 
+0

谢谢,通过了解之前发布的正则表达式,帮助我了解了! – kwintin 2013-02-14 14:27:31