在Swift中,我如何从一个随机字符串中提取一个子字符串来匹配特定的开始和结束模式

8i9zcol2  于 2023-05-27  发布在  Swift
关注(0)|答案(2)|浏览(415)

我正在尝试从SwiftUI中的String中提取一个或多个与特定模式匹配的子字符串。该模式是以6位数字开始,以$结束。
例如,在字符串中:

let str = "Some random text 034503 intermediate text $ some more random text 873234 more intermediate text $."

我想提取两个子字符串:

var subString1 = "034503 intermediate text $"
var subString2 = "873234 more intermediate text $"

我知道如何提取特定的子字符串,但在本例中,我不知道该子字符串。我只知道它以某种模式(6位数字)开始,以另一种模式($)结束。我该怎么办?

ffx8fchx

ffx8fchx1#

您可以使用正则表达式来实现这一点。您所描述的模式可以由正则表达式表示:\b\d{6}.*?\$
该表达式可以分解如下:

  • \B:单词边界。确保六位数不是较大数字的一部分。
  • \d{6}:正好是六位数。
  • .*?:任何字符,但尽可能少。
  • $:美元符号。此模式将匹配以

以六位数字结尾,并包括所有
人物之间。
以下是如何在Swift中使用它:

let str = "Some random text 034503 intermediate text $ some more random text 873234 more intermediate text $."

do {
    let regex = try NSRegularExpression(pattern: "\\b\\d{6}\\b.*?\\$", options: .caseInsensitive)
    let range = NSRange(location: 0, length: str.utf16.count)
    let matches = regex.matches(in: str, options: [], range: range)
    
    let substrings = matches.compactMap { Range($0.range, in: str) }.map { str[$0] }
    print(substrings)
    
} catch {
    print("Invalid regex: \(error.localizedDescription)")
}

在这个正则表达式模式中,\\b\\d{6}\\b将正好匹配6个数字,这些数字不是一个更大的数字的一部分。这将确保长度超过6位的数字不会被匹配。
在此代码中,compactMap用于将NSTextCheckingResult数组转换为Range<String.Index>数组。然后,使用map将范围数组转换为子字符串数组。

使用For循环

let str = "Some random text 034503 intermediate text $ some more random text 873234 more intermediate text $."

do {
    let regex = try NSRegularExpression(pattern: "\\b\\d{6}\\b.*?\\$", options: .caseInsensitive)
    let range = NSRange(location: 0, length: str.utf16.count)
    let matches = regex.matches(in: str, options: [], range: range)
    
    for match in matches {
        if let range = Range(match.range, in: str) {
            let subString = str[range]
            print(subString)
        }
    }
} catch {
    print("Invalid regex: \(error.localizedDescription)")
}

请记住,在Swift中,由于额外的函数调用,高阶函数可能会导致性能稍慢。但是,在大多数情况下,这种性能差异可以忽略不计,除非您正在处理非常大的数据集,否则不应该担心。
请记住,代码的可读性和可维护性通常比较小的性能增益更重要。您应该选择对您和其他开发人员来说可读性最强、最容易理解的版本。

fdx2calv

fdx2calv2#

这个正则表达式应该可以工作:

let r = try! Regex("\b\d{6} [^$]*\$")

或者作为正则表达式文字:

/\b\d{6} [^$]*\$/

我建议使用类似https://regex101.com的东西来创建和验证正则表达式。
以下是您的示例:https://regex101.com/r/GqCh17/1

相关问题