LLRegex 1.3.0

LLRegex 1.3.0

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布最后发布2017年9月
SwiftSwift版本4.0
SPM支持SPM

Rock Young维护。



LLRegex 1.3.0

  • 作者:
  • Rocke Young

LLRegex

Swift中的正则表达式库,封装了NSRegularExpression。无需犹豫,在playground中试试。

特性

  • 值语义
  • 使用Sequence枚举匹配
  • 命名捕获组
  • 支持范围(消除NSRange)
  • 正则表达式选项、匹配选项
  • 灵活的查找和替换
  • 字符串匹配、替换、拆分

通信

  • 如果您发现了一个bug,请打开一个问题,通常附上相关的模式。
  • 如果您有功能请求,请打开一个问题。

要求

  • iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 8.1+
  • Swift 3.0+

安装

Swift包管理器

dependencies: [
    .Package(url: "https://github.com/LittleRockInGitHub/LLRegex.git", majorVersion: 1)
]

用法

构建正则表达式

let numbers = Regex("(\\d)(\\d+)(\\d)")

let insensitive = Regex("LLRegex", options: [.caseInsensitive])

let runtimeError = Regex("")    // Runtime error would be raised

let invalid = try? Regex(pattern: "")   // nil returned

搜索

方法matches(in:options:range:)返回一个产生匹配的序列,这是唯一的搜索方法。其他所有变体都因Sequence的力量而废弃。

let s = "123-45-6789-0-123-45-6789-01234"
let subrange = s.characters.dropFirst(3).startIndex..<s.endIndex

for match in numbers.matches(in: s) {
    // enumerating
    match.matched
}

if let first = numbers.matches(in: s).first {
    // first match
    first.matched
}

let allMatches: [Match] = numbers.matches(in: s).all // all matches

let subrangeMatches = numbers.matches(in: s, options: [.withTransparentBounds], range: subrange)

for case let match in subrangeMatches.dropFirst(1) where match.matched != "6789" {
    match.matched
}
  • 重要:如果无法将匹配的范围转换为Range,则忽略该匹配。尝试在“\r\n”中搜索“\r”。

匹配与捕获组

if let first = numbers.matches(in: s).first {
    
    first.matched
    first.range
    first.groups.count
    first.groups[1].matched
    first.groups[1].range
    
    let replacement = first.replacement(withTemplate: "$3$2$1")     // Replacement with template
}

命名捕获组

当设置.namedCaptureGroups时启用命名捕获组功能。

let named = Regex("(?<year>\\d+)-(?<month>\\d+)-(?<day>\\d+)", options: .namedCaptureGroups)
let s = "Today is 2017-06-23."

for m in named.matches(in: s) {
    m.groups["year"]?.matched
}

named.replacingAllMatches(in: s, replacement: .replaceWithTemplate("${month}/${day}/${year}")) // Today is 06/23/2017.
  • 注意:如果模式中的注释包含捕获组的表示法,则会失败对命名捕获组的检测。

替换

numbers.replacingFirstMatch(in: s, replacement: .remove)

numbers.replacingAllMatches(in: s, range: subrange, replacement: .replaceWithTemplate("$3$2$1"))

灵活的查找与替换功能由 replacingMatches(in:options:range:replacing:) 提供。

numbers.replacingMatches(in: s) { (idx, match) -> Match.Replacing in
    
    switch idx {
    case 0:
        return .keep    // Keeps unchanged
    case 1:
        return .remove  // Removes the matched string
    case 2:
        return .replaceWithTemplate("($1-$3)")    // Replaces with template
    case 3:
        return .replaceWithString(String(match.matched.characters.reversed()))   // Replaces with string
    default:
        return .stop    // Stops replacing
    }
}

字符串匹配

"123".isMatching("\\d+")
"llregex".isMatching(insensitive)   // Regex is accepted
"123-456".isMatching("\\d+")    // isMatching(_:) checks whether matches entirely

字符串替换

  • 注意:有两种变体 - 一种包含模式标签和模板标签,另一种不包含。
"123".replacingAll("1", with: "$0")
"123-321".replacingAll(pattern: "(\\d)(\\d)", withTemplate: "$2$1")

s.replacingFirst(pattern: numbers, in: subrange, withTemplate: "!")

字符串分割

s.split(seperator: "\\d")
s.split(seperator: numbers, maxSplits: 2, omittingEmptyString: false)