🦖 Rexx
简化 Swift 中的正则表达式
Swift 中的正则表达式比实际需要的艰难得多。如果您在其他语言中(如 Ruby、Python 或 Perl)使用过正则表达式,您就已经知道这应该是多么简单!这个库旨在减少为仅要在字符串和正则表达式模式之间进行简单比较和从模式中的捕获组中提取值所需的基本代码。
但是不要只听我说,我为你提供了一个例子
Swift API
// 1. Your input string and the pattern. In this case, we want to check if the string starts with "Hello"
let myString = "Hello, World!"
let pattern = "^Hello"
// 2. Create an instance of NSRegularExpression with your pattern.
let regex = try! NSRegularExpression(pattern: pattern)
// 3. Define the range within the string you want to search for the pattern.
let range = NSRange(location: 0, length: myString.utf16.count)
// 4. Find the first match, if any, within the string.
let isMatch = regex.firstMatch(in: myString, options: [], range: range)
// 5. If isMatch isn't nil, we have a match!
if isMatch != nil {
print("We have a match!")
}
Rex
// 1. Your input string and the pattern. As the example above, check if the string starts with "Hello".
let myString = "Hello, World!"
let pattern = "^Hello"
// 2. Check if the string matches the pattern.
if myString =~ pattern {
print("We have a match!")
}
安装
使用
您可以选择创建 Rex
的实例,使用操作符或者使用 String
扩展。根据您的用例选择所需的选项。
如果您有能力匹配单一字符串与模式,这里也有两个操作符和两个你可以使用的方法。
Rex
使用 Rex
的实例接收一个模式和可选的 NSRegularExpression.Options
列表。如果您要匹配多个相同的字符串,或者需要提供选项,这通常是首选的方式。
Rex
有两个方法
matches(string:) -> Bool
match(string:options:) -> Match
前者仅检查模式是否与提供的字符串匹配,而后者允许您从模式中的捕获组中获取值。匹配的结果通过 Match
提供。
如果在 iOS 11 及更高版本上,您可以轻松地从命名捕获组中获取值!range(withName:)
,因此此功能在早期版本中不可用。
// 1. Define your pattern. Match against a string starting with "Hello, " and ending with "!". Capture whatever name/word we're saying hello to.
let pattern = "^Hello, (?<name>\\w+)!$"
// 2. Create an instance of Rex with the pattern. You can also provide options through the `options:` parameter.
// Please note that the instantiation may fail, hence the 'try'-keyword, if the pattern has errors. Se
let rex = try Rex(pattern: pattern)
// 3. Match against a string.
let match = rex.match("Hello, World!")
// 4.1 Fetch the name we captured within the first capture group.
if let name = match.captures.first {
print("We said hello to", name)
}
// 4.2 iOS 11+ only! Fetch the name captured within the capture group, which is a named capture group.
if let name = match.capture(withName: "name") {
print("We said hello to", name)
}
=~
& !=~
操作符:如果您只需要检查字符串是否与模式匹配,则操作符可能是使用 Rex
的最简单方法。只需将您的字符串放在操作符的 左侧,将模式放在 右侧 即可!
注意!请注意,如果您的模式是无效的 Swift 正则表达式,则这些操作符将返回 false
对于 =~
和 true
对于 !=~
。由于这些情况难以调试,但建议您在例如 RegExr 上检查您的模式,这是一个在线工具,用于测试模式。
模式匹配
如果您需要检查字符串是否与您的模式匹配,请使用 =~
操作符。如果字符串与模式匹配,则返回 true
。
if "Hello, World!" =~ "^Hello" {
// 👌 The string starts with "Hello".
}
if "123456789" =~ "^\\d+$" {
// 👌 The string contains only digits.
}
否定模式匹配
有时您可能想要检查负匹配。在这些情况下,您可以使用操作符 !=~
,如果字符串 不与 模式匹配,则它将返回 true
。
if "Only letters and-symbols_here !()?\\" !=~ "\\d" {
// 👌 The string does not contain any digits.
}
if "123456abcd" !=~ "^[a-zA-Z]" {
// 👌 The string does start with any letters.
}
字符串扩展
这些扩展用法与操作符一样简单,但的好处是它不使用自定义操作符。它们允许您检查字符串与模式匹配,或从模式中获取捕获的值。
这些方法与 Rex
的方法非常相似,但无需创建它的实例。
matches(pattern:) -> Bool
match(pattern:) -> Match
模式匹配
检查您的字符串是否匹配该模式。
if "Hello, World!".matches("^Hello") {
// 👌 The string starts with "Hello".
}
if "1234".matches("^\\d+$") {
// 👌 The string contains only digits.
}
捕获值
检查您的字符串是否匹配该模式,并从捕获组中获取值。
// Fetch the name in capture group 1, which is also a named capture group.
let pattern = "^Hello, (?<name>\\w+)!$"
let match = "Hello, World!".match(pattern)
// Get the name from the first capture group.
if let name = match.captures.first {
// 👌 The string matches, and we have the name!
}
// iOS 11+ only! Get the name from the capture group named 'name'.
if let name = match.capture(withName: "name") {
// 👌 The string matches, and we have the name!
}