测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | 自定义 |
发布最后发布 | 2017年7月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✓ |
由 Torin Kwok 维护。
几乎所有现代正则表达式引擎都支持编号捕获组和编号回溯引用。具有大量组和回溯引用的长正则表达式可能难以阅读。它们在维护方面尤其困难,因为在中部添加或删除捕获组可能会打乱之后所有组的编号。
Python、PHP 的 preg 引擎和 .NET 语言等语言或库支持捕获到命名的位置,我们称之为“命名捕获组”。命名捕获组(NCG)的一个最重要的好处是为每个单独的捕获组分配一个人类可读的名称,可能会使阅读源码的人感到不那么困惑,否则他们可能不知道哪一个数字与哪个捕获组相对应。
命名捕获组很棒。 NSRegularExpression
不支持它。
Cocoa 的 NSRegEx
实现根据苹果官方文档,是基于 ICU 的正则表达式实现
当前支持的模式语法是 ICU 规定的。ICU 正则表达式描述在 http://userguide.icu-project.org/strings/regexp。
该页面(在 http://http://site.icu-project.org)声称现在支持命名捕获组,使用与 .NET 正则表达式相同的语法
(?...) 命名捕获组。它们是文字的 - 它们出现在模式中。
例如
\b**(?\d\d\d)-(?\d\d\d)-(?**\d\d\d\d)\b
然而,苹果官方对 NSRegEx
的文档没有列出命名捕获组的语法,它只在 ICU 的文档中列出,这表明NCG是一个新增功能,因此Cocoa的实现尚未集成。
也就是说,目前通过 NSRegEx
暴露的捕获组匹配结果的唯一方法是通过在 NSTextCheckingResult
类中调用 rangeAt(:_)
方法进行数字化的。冷静下来,Cocoa。
扩展库,NSRegExNamedCaptureGroup,旨在为使用NSRegEx
的开发者提供一个直观的方式来处理正则表达式中的命名捕获组。
Carthage:
如果您使用Carthage来管理依赖项
Cartfile
github "TorinKwok/NSRegExNamedCaptureGroup" ~> 1.0.0
单击Xcode菜单栏中的文件
-> 将文件添加到 "$PROJECT_NAME"
项。选择NSRegExNamedCaptureGroup.xcodeproj
将NSRegExNamedCaptureGroup嵌入到通用
面板
CocoaPods:
要使用CocoaPods安装,将以下内容添加到您的项目Podfile中
pod 'NSRegExNamedCaptureGroup', '~>1.0.0'
Swift包管理器:
Swift包管理器是一个用于管理Swift代码分发工具。它与Swift构建系统集成,以自动下载、编译和链接依赖项的过程。
一旦您设置好Swift包,将框架添加为依赖项就像将其添加到您的Package.swift
的依赖项值一样简单。
dependencies: [
.Package( url: "https://github.com/TorinKwok/NSRegExNamedCaptureGroup.git", majorVersion: 1 )
]
Git子模块:
git submodule
命令将此仓库克隆到您的项目中git submodule add https://github.com/TorinKwok/NSRegExNamedCaptureGroup.git "$SRC_ROOT" --recursive`
Carthage
部分中的最后两个步骤相同import NSRegExNamedCaptureGroup
let phoneNumber = "202-555-0136"
// Regex with Named Capture Group.
// Without importing NSRegExNamedCaptureGroup, you'd have to
// deal with the matching results (instances of NSTextCheckingResult)
// through passing the Numberd Capture Group API:
// `rangeAt(:_)` a series of magic numbers: 0, 1, 2, 3 ...
// That's rather inconvenient, confusing, and, as a result, error prune.
let pattern = "(?<Area>\\d\\d\\d)-(?:\\d\\d\\d)-(?<Num>\\d\\d\\d\\d)"
let pattern = try! NSRegularExpression( pattern: pattern, options: [] )
let range = NSMakeRange( 0, phoneNumber.utf16.count )
使用NSRegEx
的第一次匹配便利方法
let firstMatch = pattern.firstMatch( in: phoneNumber, range: range )
// Much better ...
// ... than invoking `rangeAt( 1 )`
print( NSStringFromRange( firstMatch!.rangeWith( "Area" ) ) )
// prints "{0, 3}"
// ... than putting your program at the risk of getting an
// unexpected result back by passing `rangeAt( 2 )` when you
// forget that the middle capture group (?:\d\d\d) is wrapped
// within a pair of grouping-only parentheses, which means
// it will not participate in capturing at all.
//
// Conversely, in the case of using
// NSRegExNamedCaptureGroup's extension method `rangeWith(:_)`,
// we will only get a range {NSNotFound, 0} when the specified
// group name does not exist in the original regex.
print( NSStringFromRange( firstMatch!.rangeWith( "Exch" ) ) )
// There's no a capture group named as "Exch",
// so prints "{9223372036854775807, 0}"
// ... than invoking `rangeAt( 2 )`
print( NSStringFromRange( firstMatch!.rangeWith( "Num" ) ) )
// prints "{8, 4}"
使用基于阻塞枚举的NSRegEx
API
pattern.enumerateMatches( in: phoneNumber, range: range ) {
match, _, stopToken in
guard let match = match else {
stopToken.pointee = ObjCBool( true )
return
}
print( NSStringFromRange( match.rangeWith( "Area" ) ) )
// prints "{0, 3}"
print( NSStringFromRange( match.rangeWith( "Exch" ) ) )
// There's no a capture group named as "Exch"
// prints "{9223372036854775807, 0}"
print( NSStringFromRange( match.rangeWith( "Num" ) ) )
// prints "{8, 4}"
}
使用基于数组的NSRegEx
API
let matches = pattern.matches( in: phoneNumber, range: range )
for match in matches {
print( NSStringFromRange( match.rangeWith( "Area" ) ) )
// prints "{0, 3}"
print( NSStringFromRange( match.rangeWith( "Exch" ) ) )
// There's no a capture group named as "Exch"
// prints "{9223372036854775807, 0}"
print( NSStringFromRange( match.rangeWith( "Num" ) ) )
// prints "{8, 4}"
}