Swift 上的 RegexBuilder 入门

关于正则表达式有一句古老的格言:“有些人在遇到问题时会想:‘我知道,我会使用正则表达式。’” 现在他们有两个问题。” 这证明了正则表达式是多么混乱和复杂。

这就是 Swift 语言 5.7 版本的 RegexBuilder 的 闪光点。 RegexBuilder 简化了正则表达式的编写并使它们更具可读性。 在本文中,我们将介绍 RegexBuilder 入门,包括使用各种 RegexBuilder 组件,例如 CharacterClass, Currency, 和 date.

向前跳跃:

  • 在 Xcode 上设置 Swift Playground

  • 使用正则表达式 API

  • 正则表达式生成器 API

  • RegexBuilder 量词

  • 匹配 RegexBuilder 组件

  • 捕获匹配的文本

在 Xcode 上设置 Swift Playground

您可以在许多平台上使用 Swift 语言,Windows 11不会弹出外部硬盘驱动器? 8个修复方法包括 Linux。 Linux 支持 RegexBuilder,但在本教程中,我们将在 Mac 上使用 Swift,因为我们使用的是 UIKit库,仅在 Mac 上可用。

首先,打开 Xcode。 然后创建一个 Swift Playground 应用程序。 完成此操作后,导航到 菜单中的File 并单击 New > Playground 。 将其命名为 RegexBuilderPlayground 。 您将看到导入 UIKit 并声明变量greeting 的 默认代码:

使用正则表达式 API

在学习如何使用新的 RegexBuilder API 之前,Windows 11上的WiFi不断断开怎么办?12种修复方法您应该熟悉原始的 Regex API 。

将创建新 Playground 时获得的默认代码替换为以下代码:

import UIKit
​
let regex = /\d+@\w+/
let match = "12345@hello".firstMatch(of: regex)
print(match!.0)

编译并运行代码,您将得到以下结果:

12345@hello

正如您所看到的,正则表达式是用这种神秘的语法编写的: /\d+@\w+/.

\d表示一个数字, \d+表示一个或多个数字, @表示文字 @, \w表示单词字符,并且 \w+表示一个或多个单词字符。 这 /是正则表达式语法的边界。

下一行是如何使用正则表达式将字符串与正则表达式匹配 firstMatch方法。 结果是 match目的。 您将获得与 0方法,如果有的话。

正则表达式生成器 API

现在,是时候检查等效代码了 RegexBuilderAPI。如何修复 WhatsApp 网页二维码不起作用(10 种方法) 有一个快捷方式可以将旧的正则表达式语法转换为 RegexBuilder句法。 突出显示并右键单击旧的正则表达式语法(按住 Control 按钮的同时单击),您应该会看到一个将旧的正则表达式语法重构为新的选项 RegexBuilder句法:

新的正则表达式语法将如下所示:

let regex = Regex {
    OneOrMore(.digit)
    "@"
    OneOrMore(.word)
}

有了这个新语法,您不再需要想知道什么 \d方法。 在里面 RegexBuilderAPI,神秘的 \d+已被替换为更友好的语法, OneOrMore(.digit)。 很清楚什么 OneOrMore(.digit)方法。 与情况相同 \w+,其替换语法, OneOrMore(.word)更清楚了。

另外,请注意导入行 RegexBuilder已添加:

import RegexBuilder

RegexBuilder 量词

OneOrMore是一个量词。 在旧版 API 中,量词是 *,这意味着零个或多个, +这意味着一个或多个, ?这意味着零或一,并且 {n,m}这意味着,至少, n重复,最多, m重复。

如果你想让左边 @成为可选的,你可以使用 Optionally量词:

let regex2 = Regex {
    Optionally(.digit)
    "@"
    OneOrMore(.word)
}

上面代码的意思是 /\d?@\w+/.

如果您希望左侧至少有四位数字,如何查看您的Instagram Reels观看历史记录(5种方 法)最多六位数字,该怎么办? @? 你可以使用 Repeat:

let regex3 = Regex {
    Repeat(4...6) {
        .digit
    }
    "@"
    OneOrMore(.word)
}

匹配 RegexBuilder 组件

让我们重新开始学习 RegexBuilder从头开始。 添加以下代码:

let text = "Writer/Arjuna Sky Kok/$1,000/December 4, 2022"
let text2 = "Illustrator/Karen O'Reilly/$350/November 30, 2022"

此示例演示您为 LogRocket 工作,并且需要解析自由职业者的付款文本。 这 text变量表示 LogRocket 最迟应在 2022 年 12 月 4 日向 Arjuna Sky Kok 支付 1,000 美元的写作服务费用。 这 text2变量表示 LogRocket 应在 2022 年 11 月 30 日向 Karen O'Reilly 支付 350 美元的插图服务费用。

您希望将文本解析为四个部分,即工作部分、姓名部分、付款金额和付款截止日期。

使用 ChoiceOf来表明选择

让我们从作业组件开始。 根据上面的代码,工作要么是“作家”,要么是“插画家”。 您可以创建一个表达选择的正则表达式。

添加以下代码:

let job = Regex {
    ChoiceOf {
        "Writer"
        "Illustrator"
    }
}

正如代码中所见,如何使Windows 11任务栏完全透明您使用了 ChoiceOf来表示一个选择。 你把你想要选择的东西放进去 ChoiceOf堵塞。 您不限于两种选择。 您可以添加更多选择,但每个选择都需要专线。 在旧版 API 中,您将使用 |.

您可以将其与 text变量添加以下代码:

if let jobMatch = text.firstMatch(of: job) {
    let (wholeMatch) = jobMatch.output
    print(wholeMatch)
}

如果编译并运行该程序,您将得到以下输出:

Writer

这意味着您的正则表达式与作业组成部分匹配。 您可以使用以下命令进行测试 text2如果你愿意的话可以变量。

CharacterClass

现在,让我们继续讨论下一个组成部分:名称。 名称由一个或多个单词字符、可选空格和单引号字符定义。 一般来说,名称可能比这更复杂。 但对于我们的例子来说,这个定义就足够了。

这是您的名称组件的正则表达式:

let name = Regex {
    OneOrMore(
        ChoiceOf {
            CharacterClass(.word)
            CharacterClass(.whitespace)
            "'"
        }
    )
}

你看过 OneOrMore和 ChoiceOf。 但还有一个新组件: CharacterClass。 在旧版 API 中,这相当于 \d, \s, \w, 等等。 它是一类人物的代表。

CharacterClass(.word)表示单词字符,如 a、b、c、d 等。 CharacterClass(.whitespace)表示空白,如空格、制表符等。除了 .word和 .space,你还有 几个字符类 。 如果你想要一个数字 CharacterClass, 你可以写 CharacterClass(.digit)代表 1、2、3 等。

因此,名称由一个或多个单词字符、任意空格和单引号字符组成。

您可以尝试使用此正则表达式 text多变的:

if let nameMatch = "Karen O'Reilly".firstMatch(of: name) {
    let (wholeMatch) = nameMatch.output
    print(wholeMatch)
}

输出是您所期望的:

Karen O'Reilly

货币

现在,让我们进入下一个组成部分:付款。 您要匹配的文本是“$1,000”或“$350”。 您可以通过检查 $ 符号和可选的逗号来创建一个复杂的正则表达式来匹配这两次付款。 然而,还有一个更简单的方法:

let USlocale = Locale(identifier: "en_US")
let payment = Regex {
    One(.localizedCurrency(code: "USD", locale: USlocale))
}

你可以使用 .localizedCurrency带有美元代码和美国区域设置。 这样,您可以更改代码和区域设置,以防您想要匹配其他货币的付款,例如“¥1,000”。

正则表达式组件 One类似于 OneOrMore。 它代表表达式的精确出现一次。

将以下代码添加到文件中,然后编译并运行程序即可看到结果:

if let paymentMatch = text.firstMatch(of: payment) {
    let (wholeMatch) = paymentMatch.output
    print(wholeMatch)
}

结果与之前的结果有点不同。 你会得到:

1000

结果不是 $1,000,但是原始数字, 1000。 在幕后, RegexBuilder将匹配的文本转换为整数。

日期

日期有一个等效的正则表达式。 您想要解析日期组件, December 4, 2022。 您可以采取相同的方法。 您无需创建自定义正则表达式来解析日期。 你用一个 date正则表达式组件添加以下代码:

let date = Regex {
    One(.date(.long, locale: USlocale, timeZone: .gmt))
}

这次你用的是 .date与 .long参数、相同的区域设置和 GMT 时区。 您要解析的日期“2022 年 12 月 4 日”采用长格式。 如果您使用不同格式的日期,您将使用不同的参数。

现在,您应该通过添加以下代码并运行程序来测试它:

if let dateMatch = text.firstMatch(of: date) {
    let (wholeMatch) = dateMatch.output
    print(wholeMatch)
}

结果是日期格式,而不是确切的字符串:

2022-12-04 00:00:00 +0000

就像付款案例一样, RegexBuilder将匹配的文本转换为日期。

捕获匹配的文本

现在,您想要结合所有 RegexBuilder代码以匹配全文。 您可以堆叠所有 Regex块:

let separator = Regex { "/" }
let regexCode = Regex {
    job
    separator
    name
    separator
    payment
    separator
    date
}

因此,您可以为变量提供一个子集正则表达式,并在更大的变量中使用它 Regex堵塞。

然后你应该用这两个文本来测试它:

if let match = text.firstMatch(of: regexCode) {
    let (wholeMatch) = match.output
    print(wholeMatch)
}
​
if let match2 = text2.firstMatch(of: regexCode) {
    let (wholeMatch) = match2.output
    print(wholeMatch)
}

输出是完美的:

Writer/Arjuna Sky Kok/$1,000/December 4, 2022
Illustrator/Karen O'Reilly/$350/November 30, 2022

但我们并不满足,因为我们想要捕获每个组件,趣知笔记 - 分享有价值的教程!而不是整个组件。 添加以下代码:

let regexCodeWithCapture = Regex {
    Capture {
        job
    }
    separator
    Capture {
        name
    }
    separator
    Capture {
        payment
    }
    separator
    Capture {
        date
    }
}

我们将要捕获的组件放入 Capture堵塞。 在本例中,我们将四个组件放入块内。

这样,当将文本与正则表达式匹配时,就可以访问捕获的组件。 在遗产中 RegexAPI,我们称之为反向引用。 添加以下代码来获取捕获的组件:

if let matchWithCapture = text.firstMatch(of: regexCodeWithCapture) {
    let (wholeMatch) = matchWithCapture.output
    print(wholeMatch.0)
    print(wholeMatch.1)
    print(wholeMatch.2)
    print(wholeMatch.3)
    print(wholeMatch.4)
}

编译并运行该程序,您将得到以下输出:

Writer/Arjuna Sky Kok/$1,000/December 4, 2022
Writer
Arjuna Sky Kok
1000
2022-12-04 00:00:00 +0000

这 0方法指的是完全匹配。 这 1方法指向第一个捕获的组件,即作业组件。 然后 2是为了名字, 3用于付款,并且 4是为了日期。 你没有 5方法,因为您只捕获了四个组件。

结论

在本文中,您学习了如何使用编写正则表达式 RegexBuilder。 您首先使用旧 API 编写正则表达式,然后将其转换为新语法。 这表明正则表达式如何变得更易于阅读。 您复习了一些概念,例如量词、选择、字符类、货币和日期。 最后,您捕获了正则表达式的组成部分。

本文仅触及皮毛 RegexBuilder。 有些东西你还没有学到,比如重复行为和使用捕获组件 TryCapture。 还可以了解它的演变过程 RegexBuilderAPI 位于 此处的文档 中。 本文的代码可在此 GitHub 存储库 中找到。

猜你喜欢

转载自blog.csdn.net/weixin_47967031/article/details/132836483
今日推荐