NSRegularExpression 与 Swift 中的模板

Posted

技术标签:

【中文标题】NSRegularExpression 与 Swift 中的模板【英文标题】:NSRegularExpression with template in Swift 【发布时间】:2015-05-29 04:09:57 【问题描述】:

我正在使用代码获取对 HTTP POST 请求的响应

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) data, response, error in

if error != nil 
println("error=\(error)")
return

// Get the response to the HTTP POST
var responseString = NSString(data: data, encoding: NSUTF8StringEncoding)!
task.resume()

我试图定义两个正则表达式

let regex0: NSRegularExpression = NSRegularExpression(pattern: "<b>District Representatives:</b>", options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: nil)!

let regex1: NSRegularExpression = NSRegularExpression(pattern: "\\A.*<b>District Representatives:</b>.*href=\"http://www\.sec\.state\.ma\.us/ele/eledist/con11idx\.htm#D[1-9]\" target=\"_blank\">(.*?)</a>.*href=\"http://www\.sec\.state\.ma\.us/ele/eledist/sen11idx\.htm#[0-9]0,5[a-z]1,20\" target=\"_blank\">(.*?)</a>.*\"http://www\.sec\.state\.ma\.us/ele/eledist/reps11idx\.htm#[a-z]1,13[0-9]0,2\" target=\"_blank\">(.*?)</a>.*\\z", options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: nil)!

但是 Xcode 给了我关于 regex1 定义的错误信息“Expected expression”。

我想测试responseString是否被regex0匹配。我尝试使用

var numberOfMatches: Int = regex0.numberOfMatchesInString(responseString, options:nil, range: (NSMakeRange(0, responseString.length)))

但我收到错误消息“使用未解析的标识符响应字符串”

我想知道如何测试正则表达式匹配是否成功。在这种情况下,我可以测试 responseString 是否包含我的测试字符串。这似乎适用于 Swift Strings,但我无法让它与 NSString 一起使用。

我认为我的 regex1 正则表达式中的模式是可以的,因为我在 TextWrangler 中测试了等效模式。我在那里使用的模式是

(?s)\A.*<b>District Representatives:</b>.*href="http://www\.sec\.state\.ma\.us/ele/eledist/con11idx\.htm#D[1-9]" target="_blank">(.*?)</a>.*href="http://www\.sec\.state\.ma\.us/ele/eledist/sen11idx\.htm#[0-9]0,5[a-z]1,20" target="_blank">(.*?)</a>.*"http://www\.sec\.state\.ma\.us/ele/eledist/reps11idx\.htm#[a-z]1,13[0-9]0,2" target="_blank">(.*?)</a>.*\z

唯一的(有意的)区别在于,在 Swift 文字中,所有双引号和反斜杠都必须用反斜杠转义,并且 TextWrangler 模式以 (?s) 开头,这相当于 NSRegularExpressionOptions.DotMatchesLineSeparators。

我想用regex1来修改responseString如下

responseString.replaceMatchesInString(options: nil, range: NSMakeRange(0, responseString.length), withTemplate template: "$1\t$2\t$3")

但这也没有用。

我天真地认为,自从我使用正则表达式 30 年以来,这部分会很容易。显然不是。

【问题讨论】:

【参考方案1】:

您的regex1 在文字点上缺少双转义符(请参阅www\.sec\.state\.ma\.us)。

正确的 regex1 声明将是

@"\\A.*<b>District Representatives:</b>.*href=\"http://www\\.sec\\.state\\.ma\\.us/ele/eledist/con11idx\\.htm#D[1-9]\" target=\"_blank\">(.*?)</a>.*href=\"http://www\\.sec\\.state\\.ma\\.us/ele/eledist/sen11idx\\.htm#[0-9]0,5[a-z]1,20\" target=\"_blank\">(.*?)</a>.*\"http://www\\.sec\\.state\\.ma\\.us/ele/eledist/reps11idx\\.htm#[a-z]1,13[0-9]0,2\" target=\"_blank\">(.*?)</a>.*\\z"

使用未解析的标识符 responseString 可能是因为您在声明和使用 numberOfMatches 的方法之外声明了 responseString

【讨论】:

谢谢。该修复消除了关于 regex1 定义的错误消息。 “使用未解决的标识符 responseString”问题似乎是我剩下的许多困难的根源。我认为我必须先解决这个问题,然后才能重新处理正则表达式问题。 请使用正则表达式和响应字符串发布您的完整代码,或者如果太长,请使用pastebin 请看this question的回答。这有帮助吗? 感谢@stribizhev 的帮助。我将当前程序(减去一些垃圾)放在pastebin.com/HwNLxbi9 的 Pastenbin 上。在***.com/questions/30418955/… 的问题中,我试图给出我的程序模板(不包括做有用工作的部分)。现在,我的主要问题是我想要一个同步循环,而 Xcode 想要我有异步任务。

以上是关于NSRegularExpression 与 Swift 中的模板的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 和 NSRegularExpression

NSRegularExpression如何让NSRange超出范围?

非贪婪的 NSRegularExpression

NSRegularExpression 中的命名捕获组 - 获取范围组的名称

如何在Objective C(NSRegularExpression)中编写正则表达式?

捕获组在 NSRegularExpression 中不起作用