【问题标题】:Phone number Regex not working with swift [duplicate]电话号码正则表达式不适用于 swift [重复]
【发布时间】:2016-03-11 06:49:33
【问题描述】:

我正在开发一个适用于电话号码的应用程序,但我在使用正则表达式查找字符串中的电话号码时遇到了问题。

我的应用会查看联系人的电话号码,可以是:

(带破折号“-”)
XXXX-XXXX
XXXXX-XXXXX
(YY) XXXX-XXXX
(YY) XXXX-XXXX
+ZZ (YY) XXXX-XXXX
+ZZ (YY) XXXXX-XXXX


(不带破折号)
XXXXXXX
XXXXXXXXX
(YY) XXXXXXX
(YY) XXXXXXXXX
+ZZ (YY) XXXXXXX
+ZZ (YY) XXXXXXXXX

基于以上所有这些可能性,我编写了以下代码:

    let range = telefone.rangeOfString("[0-9]{4,5}-[0-9]{4}", options:.RegularExpressionSearch)
    let range2 = telefone.rangeOfString("[0-9]{9}$", options:.RegularExpressionSearch)

    var found: String?

    if range != nil{
        found = telefone.substringWithRange(range!)
    }else if range2 != nil{
        found = telefone.substringWithRange(range2!)
    }

    print(found)

range 是查找电话号码的正则表达式(带破折号“-”)
range2 是为电话号码提供资金的正则表达式(不带破折号)

有了这个代码,我只得到电话号码,没有国家代码或区号。

问题是,当我使用
+ZZ (YY) XXXXX-XXXX 之类的电话号码进行测试时,此代码在找到的变量上返回 nil

有人可以帮我找到另一种方法来编写一个正则表达式来仅获取包含所有联系电话号码的字符串的“X”值吗?

更新:

我注意到上面的代码,变量范围,返回null

    var telefone = "+42 43 23123-2221"

    let range = telefone.rangeOfString("\\d{4,5}\\-?\\d{4}", options:.RegularExpressionSearch)

    print("range \(range)")   //here returns nil

【问题讨论】:

  • 是否总是 2、2、(4 或 5)、4 模式?您可以使用简单的(?:\d{2}\D*){0,2}\d{4,5}\D*\d{4} 或更多保证(?<!\d)(?:\d{2}\D*){0,2}\d{4,5}\D*\d{4}(?!\d)
  • 这个将捕获部分 grps 1-4。 (?<!\d)(?:(\d{2})\D*)?(?:(\d{2})\D*)?(\d{4,5})\D*(\d{4})(?!\d)demo
  • 根据您的回答,我使用了\d{4,5}\-?\d{4},这是我需要的数字部分。但它没有找到使用 .rangeOfString("\\d{4,5}\\-?\\d{4}", options:.RegularExpressionSearch)。我已经用完整的代码更新了我的问题。谢谢!!
  • this code 适合你吗?
  • 我刚刚意识到正则表达式不支持这种格式。这是working onepattern = "(?:(?:\\+\\d{2}\\h*)?(?:\\(\\d{2}\\)|\\d{2}))?\\h*(\\d{4,5}-?\\d{4})"。请注意,OP 中未提及此电话号码格式。

标签: regex swift


【解决方案1】:

这是解决方案,看起来有点长但效果很好。

([+]?1+[-]?)?+([(]?+([0-9]{3})?+[)]?)?+[-]?+[0-9]{ 3}+[-]?+[0-9]{4}

它适用于:

5417543010
541-754-3010
(541)754-3010
(541)-754-3011
+1-541-754-3010
1-541-754-3010

【讨论】:

    【解决方案2】:

    我找到了解决办法!

    问题是电话中的连字符是 U+002D HYPHEN-MINUS,其中 phoneNumberRegEx 中的连字符是 U+2011 NON-BREAKING HYPHEN。当我在 U+002D 上标准化所有内容时,代码在操场上运行。

    【讨论】:

      【解决方案3】:

      如果括号是选项,即。 “+42 (43) 23123-2221”或“+42 43 23123-2221”:

      (?:(\+\d\d\s+)?((?:\(\d\d\)|\d\d)\s+)?)(\d{4,5}\-?\d{4})
      

      如果需要括号,也可以选择:

      (?:(\+\d\d\s+)?(\(\d\d\)\s+)?)(\d{4,5}\-?\d{4})
      

      根据您的间距要求,您可能想用一个空格 替换 \s+

      另请注意,您可能需要在开头添加锚点 ^,在末尾添加 $,以确保字符串完全匹配。

      https://regex101.com/r/bR5uM3/2

      http://swiftstub.com/44951173

      var telefone = "+42 43 23123-2221"
      
      // Use this regular expression to require "+42 (43) 23123-2221" brackets
      //let phoneNumberRegEx = "(?:(\\+\\d\\d\\s+)?(\\(\\d\\d\\)\\s+)?)(\\d{4,5}\\-?\\d{4})";
      
      
      // Use this regular expression to make them optional "+42 43 23123-2221" brackets
      let phoneNumberRegEx = "(?:(\\+\\d\\d\\s+)?((?:\\(\\d\\d\\)|\\d\\d)\\s+)?)(\\d{4,5}\\-?\\d{4})";
      
      let range = telefone.rangeOfString(phoneNumberRegEx, 
          options:.RegularExpressionSearch)
      
      print("range \(range)")
      
      var found = telefone.substringWithRange(range!)
      
      print(found)
      
      
      
      let regex = try! NSRegularExpression(pattern: phoneNumberRegEx, options: [])
      
      let telephoneRange = NSMakeRange(0, telefone.characters.count)
      let result = regex.firstMatchInString(telefone, options: NSMatchingOptions(rawValue: 0), range: telephoneRange)
      let r1 = result!.rangeAtIndex(1)
      let r2 = result!.rangeAtIndex(2)
      let r3 = result!.rangeAtIndex(3)
      if (r1.length > 0) {
          let phoneCountry = (telefone as NSString).substringWithRange(r1)
          print("country: \(phoneCountry)")
      }
      if (r2.length > 0) {
          let phoneArea = (telefone as NSString).substringWithRange(r2)
          print("area: \(phoneArea)")
      }
      if (r3.length > 0) {
          let phone = (telefone as NSString).substringWithRange(r3)
          print("phone: \(phone)")
      }
      

      这将返回以下结果:

      range Optional(Range(0..<17))
      +42 43 23123-2221
      country: +42
      area: 43
      phone: 23123-2221
      

      【讨论】:

      • 我使用了正则表达式 (\\d{4,5}\\-?\\d{4}) 因为我只想要 XXXX-XXXX 和 XXXXX-XXXX,但它只适用于在线编译器,但在操场上不起作用。我认为这是一个错误。你能在 xcode 上运行这段代码吗?
      • 我添加了一个 swiftstub 链接,向您展示代码的工作原理和进一步的代码,以展示如何使用捕获组和提取部分电话号码
      • 谢谢!!我今天回家看看,把结果贴在这里!
      • 我认为问题出在我的 IDE 上,或者是一个快速错误。看看这个code running on playground 和你在在线编译器上运行的一样
      • 尝试更新 XCode developer.apple.com
      【解决方案4】:

      这可能不是最令人愉快的正则表达式,但我相信它可以完成工作。

      (\+\d{2}\s*(\(\d{2}\))|(\(\d{2}\)))?\s*\d{4,5}\-?\d{4}
      

      演示:https://regex101.com/r/gM4uT3/3

      编辑:

      如果我理解正确,这只会匹配捕获组内没有任何区号等(只是 Xs)的电话号码。

      (?:\+\d{2}\s*(?:\(\d{2}\))|(?:\(\d{2}\)))?\s*(\d{4,5}\-?\d{4})
      

      演示:https://regex101.com/r/gM4uT3/6

      【讨论】:

      • 我用新的正则表达式更新了我的问题。但它还没有工作,它没有在字符串中找到范围。
      猜你喜欢
      • 2011-09-04
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      • 2011-02-20
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多