【问题标题】:Target double quotes using regular expressions in Swift在 Swift 中使用正则表达式定位双引号
【发布时间】:2017-07-07 19:29:23
【问题描述】:

我一直在尝试使用 Swift 中的正则表达式在字符串中提取一段文本。我要提取的文本在双引号内,因此我试图定位那些双引号并获取其中的一段文本。

这是我正在使用的正则表达式:(?<=")(?:\\.|[^"\\])*(?=")

它适用于任何类型的文本,而且它可能更简单,因为我正在寻找可能包含在这些双引号内的任何内容。

当我尝试将此 RegExp 与 Swift 一起使用时,我必须对其中的双引号进行转义,但由于某种原因,RegExp 不适用于转义的双引号,例如(?<=\")(?:\\.|[^\"\\])*(?=\").

即使我尝试一些像 \" 这样简单的方法,RegExp 也不匹配字符串中的任何双引号。

代码示例

func extractText(sentence: String?) -> String {
    let pattern = "(?<=\")(?:\\.|[^\"\\])*(?=\")"
    let source = sentence!

    if let range = source.range(of: pattern, options: .regularExpression) {
        return "Text: \(source[range])"
    }

    return ""
}

extractText("Hello \"this is\" a test") -> "this is"

记住:

  • 所有这些正则表达式都必须包含在双引号内才能创建将用作模式的字符串文字。
  • 我正在使用 String 的 range 方法和 .regularExpression 选项来匹配内容。
  • 我将 Swift 4 与 Xcode 9 Playground 一起使用

如何在 Swift 中转义双引号以成功匹配字符串中的双引号?

解决方案

感谢@Atlas_Gondal 和@vadian,我注意到问题“部分”不是正则表达式,而是我得到的字符串使用了不同类型的双引号“ ... ”,所以我必须将我的模式更改为喜欢这个"(?&lt;=“).*(?=”)" 以便使用它。

生成的代码如下所示:

func extractText(sentence: String?) -> String {
    let pattern = "(?<=“).*(?=”)"
    let source = sentence!

    if let range = source.range(of: pattern, options: .regularExpression) {
        return "\(source[range])"
    }

    return ""
}

【问题讨论】:

  • 在开场报价前有可能转义。这个(?&lt;!\\") 阻止它匹配。所以,现在总共是(?&lt;!\\")(?&lt;=")
  • 顺便说一句,所有正则表达式引擎都将(?&lt;=\") 解释为(?&lt;="),所以如果它现在不工作,那就是语言解析字符串时的问题。
  • 现在提取整个字符串中的单引号单词。如果字符串有多个带引号的单词,则它不起作用。有什么帮助吗?

标签: regex swift


【解决方案1】:

range(of 和 regularExpression 选项不能这样做,因为它无法捕获组。

你需要真实的 NSRegularExpression

func extractText(sentence: String) -> String {
    let pattern = "\"([^\"]+)\""
    let regex = try! NSRegularExpression(pattern: pattern)


    if let match = regex.firstMatch(in: sentence, range: NSRange(sentence.startIndex..., in: sentence)) {
        let range = Range(match.range(at: 1), in: sentence)!
        return String(sentence[range])
    }

    return ""
}

extractText(sentence:"Hello \"this is\" a test")

该模式要简单得多:搜索双引号,后跟一个或多个非双引号字符,然后是右双引号。捕获双引号之间的字符。

请注意,文字字符串中的转义双引号只是虚拟转义。

PS:如果没有 Swift 3 和 4 中的参数标签,您的代码将无法编译。

【讨论】:

  • 现在提取整个字符串中的单引号单词。如果字符串有多个带引号的单词,则它不起作用。有什么帮助吗?
  • @nr5 而不是firstMatch 使用matches 并使用循环来迭代数组。
【解决方案2】:

试试这个代码:

extension String {
func capturedGroups(withRegex pattern: String) -> [String] {
    var results = [String]()

    var regex: NSRegularExpression
    do {
        regex = try NSRegularExpression(pattern: pattern, options: [])
    } catch {
        return results
    }

    let matches = regex.matches(in: self, options: [], range: NSRange(location:0, length: self.characters.count))

    guard let match = matches.first else { return results }

    let lastRangeIndex = match.numberOfRanges - 1
    guard lastRangeIndex >= 1 else { return results }

    for i in 1...lastRangeIndex {
        let capturedGroupIndex = match.rangeAt(i)
        let matchedString = (self as NSString).substring(with: capturedGroupIndex)
        results.append(matchedString)
    }

    return results
}
}

使用这样的扩展:

print("This is \"My String \"".capturedGroups(withRegex: "\"(.*)\""))

示例截图

【讨论】:

    猜你喜欢
    • 2013-05-10
    • 2011-09-15
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多