如何在Swift中使用正则表达式?

Ant*_*ony 6 regex swift

我在Swift中创建一个应用程序,我需要从字符串中捕获8个数字.这是字符串: index.php?page=index&l=99182677

我的模式是: &l=(\d{8,})

这是我的代码:

var yourAccountNumber = "index.php?page=index&l=99182677"
let regex = try! NSRegularExpression(pattern: "&l=(\\d{8,})", options: NSRegularExpressionOptions.CaseInsensitive)
let range = NSMakeRange(0, yourAccountNumber.characters.count)
let match = regex.matchesInString(yourAccountNumber, options: NSMatchingOptions.Anchored, range: range)
Run Code Online (Sandbox Code Playgroud)

首先,我不知道NSMatchingOptions官方的Apple库上有什么方法,我没有得到所有的.Anchored,.ReportProgress等东西.任何人都可以照亮我吗?

然后,当我print(match),那个变量([])似乎没有任何内容.

我正在使用Xcode 7 Beta 3和Swift 2.0.

Wik*_*żew 8

原始答案

这是一个可以用来获取捕获的组文本的函数:

import Foundation

extension String {
    func firstMatchIn(string: NSString!, atRangeIndex: Int!) -> String {
        var error : NSError?
        let re = NSRegularExpression(pattern: self, options: .CaseInsensitive, error: &error)
        let match = re.firstMatchInString(string, options: .WithoutAnchoringBounds, range: NSMakeRange(0, string.length))
        return string.substringWithRange(match.rangeAtIndex(atRangeIndex))
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

var result = "&l=(\\d{8,})".firstMatchIn(yourAccountNumber, atRangeIndex: 1)
Run Code Online (Sandbox Code Playgroud)

1atRangeIndex: 1将提取由捕获文本(\d{8,})捕获组.

注1:如果您计划提取8,只有8位后&l=,你不需要,在限制量词,如{8,}意味着8个或更多.{8}如果您打算仅捕获8位数,请更改为.

注意2:NSMatchingAnchored如果您的预期结果不在搜索范围的开头,您希望避免这种情况.见文档:

指定匹配仅限于搜索范围开头的匹配.

注3:谈到"最简单"的事情,我建议你不要在不必要的时候使用环顾四周.环视通常会带来性能成本,如果您不打算捕获重叠文本,我建议使用捕获组.

SWIFT更新2

我已经提出了一个函数,它将返回所有匹配所有捕获组(类似于preg_match_allPHP).这是一种将它用于您的场景的方法:

func regMatchGroup(regex: String, text: String) -> [[String]] {
do {
    var resultsFinal = [[String]]()
    let regex = try NSRegularExpression(pattern: regex, options: [])
    let nsString = text as NSString
    let results = regex.matchesInString(text,
        options: [], range: NSMakeRange(0, nsString.length))
    for result in results {
        var internalString = [String]()
        for var i = 0; i < result.numberOfRanges; ++i{
            internalString.append(nsString.substringWithRange(result.rangeAtIndex(i)))
        }
        resultsFinal.append(internalString)
    }
    return resultsFinal
   } catch let error as NSError {
       print("invalid regex: \(error.localizedDescription)")
       return [[]]
   }
}
// USAGE:
let yourAccountNumber = "index.php?page=index&l=99182677"
let matches = regMatchGroup("&l=(\\d{8,})", text: yourAccountNumber)
if (matches.count > 0) // If we have matches....
{ 
    print(matches[0][1]) //  Print the first one, Group 1.
}
Run Code Online (Sandbox Code Playgroud)

  • @zaph,无论何时有人使用扩展方法,你似乎都会产生这个引用.我没有看到自由函数(与扩展相对)和简单性之间的联系.你是说Beck不提倡方法,只提供明确的`this`的自由函数? (2认同)
  • 扩展并不比顶级功能"更复杂".用例是您只需在值上键入一个点,然后滚动浏览其类型的所有方法和扩展.因此,您的扩展程序更容易被发现并且更有可能被使用.如果我有一个顶层函数,其主要目的是处理传入的一个数据,我可能会将其移动到该数据类型的扩展中.此外,像方法一样链接扩展的能力通常会使代码更具可读性. (2认同)