关于正则表达式有一句古老的格言:“有些人在遇到问题时会想:‘我知道,我会使用正则表达式。’” 现在他们有两个问题。” 这证明了正则表达式是多么混乱和复杂。
这就是 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 存储库 中找到。