如何创建输出自定义类型的 Swift Regex?

2023-12-02

In the 全球开发者大会视频,结果表明你可以这样做Captures/TryCapture正则表达式生成器中的 s:

let regex = Regex {
  // ...

  TryCapture {
    OneOrMore(.digit)
  } transform: {
    Int($0)
  }

  // ...
}

和输出Regex将是类型安全的。这Regex将输出一个Int对于该组,而不是Substring像平常一样。

但是,我想做的是改变整个输出类型Regex,就像应用一个transform:在结束时Regex关闭。例如,要解析包含一个人的姓名、年龄和出生日期的行:

John (30) 1992-09-22

我想做这样的事情:

// this doesn't work and is just for illustration - there is no such Regex.init
let regex = Regex {
    Capture(/\w+/)
    " ("
    TryCapture(/\d+/) { Int($0) }
    ") "
    Capture(.iso8601Date(timeZone: .gmt))
} transform: { (_, name, age, dob) in
    Person(name: String(name), age: age, dob: dob)
}

我希望regex属于类型Regex<Person>, 并不是Regex<(Substring, Substring, Int, Date)>。那是,someString.wholeMatch(of: regex).output将是一个字符串,而不是一个元组。

我基本上只是想减少元组的出现,因为我发现使用它们非常不方便,尤其是未命名的元组。自从RegexComponent由无约束参数化RegexOutput类型,并且有内置类型,其中RegexOutput is Date and Decimal,使用正则表达式对任意类型执行此操作当然不是不可能的,对吗?

我的尝试是:

struct Person {
    let name: String
    let age: Int
    let dob: Date
}
let line = "John (30) 1992-09-22"
let regex = Regex {
    Capture {
        Capture(/\w+/)
        " ("
        TryCapture(/\d+/) { Int($0) }
        ") "
        Capture(.iso8601Date(timeZone: .gmt))
    } transform: { (_, name, age, dob) in
        Person(name: String(name), age: age, dob: dob)
    }
}
line.wholeMatch(of: regex)

但这在运行时崩溃了,给出了以下消息:

无法将类型“Swift.Substring”(0x7ff865e3ead8)的值转换为“(Swift.Substring,Swift.Substring,Swift.Int,Foundation.Date)”(0x7ff863f2e660)。

我的另一个尝试使用CustomConsumingRegexComponent显示在这个答案中,但这有一个很大的警告,即它不能正确回溯。

我怎样才能创建一个Regex输出我自己的类型?


根据我在样本中读到/看到的内容(例如快速正则表达式),创建一个类似于的正则表达式组件可能是个好主意.word, .digit,但是嵌套captures似乎工作并不容易。

这是在操场上运行的示例,用于创建Person struct实例:

public static func regexBuilderMatching(string: String = "John (30) 1992-09-22") {

    struct Person: CustomStringConvertible {
        let name: String
        let age: Int
        let dob: Date

        public func dobToFormatterString() -> String {
            let dateFormatter = DateFormatter()
            // 1992-09-22 04:00:00 +0000
            dateFormatter.dateFormat = "yyyy-MM-dd"
            return dateFormatter.string(from: self.dob)
        }
        
        var description: String {
            return "\(name), age: \(age), has dob: \(dobToFormatterString())"
        }
    }

    func dateFromString(dateString: String) -> Date? {
        let formatter = DateFormatter()
        formatter.timeStyle = .none // removes time from date
        formatter.dateStyle = .full
        formatter.dateFormat = "y-MM-d" // 1992-09-22
        return formatter.date(from: dateString)
    }

    let regexWithBasicCapture = Regex {
        /* 1. */ Capture { OneOrMore(.word) }
        /* 2. */ " ("
        /* 3. */ TryCapture { OneOrMore(.digit) }
                    transform: { match in
                        Int(match)
                    }
        /* 4. */ ") "
        /* 5. */ TryCapture { OneOrMore(.iso8601Date(timeZone: .gmt)) }
                    transform: { match in
                        dateFromString(dateString: String(match))
                    }
    }

    let matches = string.matches(of: regexWithBasicCapture)
    for match in matches {
        // shorthand syntax using match output
        // https://developer.apple.com/documentation/swift/regex/match
        let (_, name, age, date) = match.output
        let person = Person(name: String(name), age: age, dob: date)
        print(person)
    }
}

上面的代码将输出:

John, age: 30, has dob: 1992-09-22
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建输出自定义类型的 Swift Regex? 的相关文章

  • 使用 CommonCrypto 的 Swift AES 加密

    我正在开发一个 iOS 应用程序代码7 1 with 斯威夫特2 1我正在尝试进行简单的加密AES 128 位 and PKCS7填充使用通用加密库 该代码有效 但每次我尝试投射NSData反对NSString然后对于 String 我得到
  • 获取键盘高度在 iOS 11 beta 上不起作用

    我有以下在 IOS 10 上运行的代码 但现在在 IOS 11 beta 上运行时不再运行 if let userInfo notification userInfo if let keyboardSize userInfo UIKeybo
  • JavaScript 使用正则表达式验证电话号码

    问候溢出者 我正在尝试编写一个正则表达式来验证 10 位数字 形式的电话号码 即 以下情况是有效的 1231231234 或 1111111111 无效的情况是少于 10 位或多于 10 位的数字字符串 到目前为止我的表达是这样的 d 10
  • Swift MKAnnotationView 旋转

    我试图在坐标更改时旋转我的自定义注释 我可以成功地更改坐标 但尝试了一切方法来旋转它 但没有成功 基本思想是有一个平面并通过旋转设置其方向 这是我的代码 import UIKit import MapKit class CustomPoin
  • 使用正则表达式验证字符串是否安全

    我有一个网站 用户可以在其中选择用户名 目前 他们可以输入几乎任何字符 包括 ETC 我知道我可以使用正则表达式 这可能就是我的选择 我将使用否定集 我认为这是正确的工具 如下所示 那么 我怎样才能知道要放入该集合中的所有非法字符呢 我可以
  • 在 Swift 中使用显式对象类型迭代数组

    我有一个数组 let individualScores 75 43 103 87 12 我这样迭代 for score in individualScores 但是 有没有办法显式声明对象类型呢 我认为以后使用自定义对象或其他原因它会派上用
  • 从文件中删除包含非英语 (Ascii) 字符的行

    我有一个文本文件 其中包含来自不同语言的字符 例如 中文 拉丁文等 我想删除包含这些非英语字符的所有行 我想包含所有英文字符 a b 数字 0 9 和所有标点符号 我如何使用 awk 或 sed 等 unix 工具来完成此操作 Perl 支
  • 为什么数组不符合 Equatable,而它的项在 Swift 中是 Equatable?

    UPDATE 从 Xcode 9 3 开始 包括斯威夫特 4 1 数组相等按预期工作 并且原始问题中的代码编译没有错误 然而 请查看已接受的答案 因为它提供了更好 更现代的解决方案 原问题如下 当我尝试声明类型为泛型枚举的实例时 Post
  • 在 wkwebview 中启用摄像头和麦克风访问

    我有一个针对移动设备优化的网络应用程序 它利用getUserMedia访问网络摄像头和麦克风资源 我正在将这个应用程序包装在WKWebView因为我想提供原生应用程序体验 我知道 iOS 不允许通过浏览器访问相机 但是有什么方法可以使用本机
  • 变量 p 在初始化之前通过引用传递

    我有一个 Human 类 它的函数可以接受任意数量的人 并确定某人是否比这些人中的任何人年长 然后返回一个包含他 她比其年长的人的数组 func isOlderThan people Human gt Human var p Human f
  • 在前两个冒号上分割字符串

    我想在前两个冒号上拆分一列字符串 但不在任何后续冒号上拆分 my data lt read table text my string some data 123 34 56 78 100 87 65 43 21 200 a4 b6 c888
  • 为什么 C# 编译的正则表达式比等效的字符串方法更快?

    每次我必须对字符串执行简单的包含或替换操作 其中我正在搜索的术语是固定值 时 我发现如果我获取示例输入并对其进行一些分析 则使用编译的正则表达式是几乎 总是比使用 String 类中的等效方法更快 我尝试过比较多种方法 hs是要搜索的 干草
  • std::regex 转义正则表达式中使用的特殊字符

    我是字符串来创建一个std regex FILE 作为单元测试的一部分 检查一些打印文件名的异常输出 在 Windows 上失败并显示 regex error error escape 表达式包含无效的转义字符或尾随转义 因为 FILE 宏
  • 在 Swift 3 中打印

    我想知道这两种在 Swift 中打印对象的方法有什么不同 结果看起来是一样的 var myName String yohoo print My name is myName print My name is myName 功能上几乎没有区别
  • 如何在 UIImagePickerController 捕获图像的瞬间获取当前位置?

    我研究了如何从返回的图像中获取位置数据UIImagePickerController相机 但是 我认为最简单的方法是获取当前位置CLLocationManager此刻UIImagePickerController捕获图像 有办法做到这一点吗
  • 在 Google Doc Apps 脚本中使用 RegEx 来替换文本

    Google 文档中有一行带有时间和日期戳 我已经使用正则表达式编写了以下代码 将该行替换为当前时间 日期 但我不确定为什么这不起作用 function UpdateDate var document DocumentApp getActi
  • R tidyr regex:从字符列中提取有序数字

    假设我有一个像这样的数据框 df lt data frame x c This script outputs 10 visualizations This script outputs 1 visualization This script
  • 如何在多行中使用 JavaScript 正则表达式?

    var ss pre aaaa nbbb nccc pre ddd var arr ss match
  • 何时使用 takeUnretainedValue() 或 takeRetainedValue() 来检索 Swift 中的非托管对象?

    根据将 Swift 与 Cocoa 和 Objective C 结合使用 https developer apple com library prerelease ios documentation Swift Conceptual Bui
  • Preg_split 用逗号,忽略括号,PHP

    我必须分割一个字符串 并且我想避免用括号内的逗号分割它 那么我该如何实现呢 Example string string1 sString1 sString2 ssString1 ssString2 string2 string3 resul

随机推荐