0

我对 swift 很陌生,我正在尝试编写一个简单的正则表达式应用程序,该应用程序接受用户输入文件路径并将几个正则表达式替换应用于文本文件。

import Foundation

let shotFilePath = readLine()
// Use contentsOfFile overload.
// ... Specify utf8 encoding.
// ... Ignore errors.
let babySteps = try NSString(contentsOfFile: shotFilePath!,
    encoding: String.Encoding.utf8.rawValue)

let firetruck = #"Ay Ay Sir!"#
var firetruckYou = babySteps.replacingOccurrences(of: firetruck, with: "", options: .regularExpression)

问题出在最后一行代码上。使用硬编码的字符串,一切正常,但是当我允许用户输入它时,我收到以下错误:

  • 调用中缺少参数“范围”的参数

如果我将 babySteps 字符串硬编码为常量,没问题,但如果我从文件中导入它,事情就会变糟。

是什么导致 Swift 在这两种情况下表现不同?提前谢谢了!

4

2 回答 2

0

我不知道为什么最初发布这个的人删除了他的答案,但这是他非常优雅的解决方案:

let babySteps = try String(contentsOfFile: shotFilePath!, encoding: .utf8)

感谢 Mojtaba,他后来也指出了 String 和 NSString 之间的区别!

于 2020-05-16T19:30:09.697 回答
0

您必须将范围传递给NSString方法。例如:

let range = babySteps.range(of: String(babySteps))

为什么?

因为你正在使用NSString. 在 Swift 中,我们更喜欢使用它String。它们不一样。看看这两个:

babyStepsString.replacingOccurrences(of: firetruck,
                                     with: "",
                                     options: .regularExpression,
                                     range: <#Range<String.Index>?#>)

babyStepsNSString.replacingOccurrences(of: firetruck,
                                       with: "",
                                       options: .regularExpression,
                                       range: <#NSRange#>)

正如您所看到的,这两种方法几乎相同,但是该String方法采用 anoptional并且您可以传递nil或不传递任何东西给它,因为它具有默认nil值。但是NSString版本要求您通过一个范围。


升级

你可以实现一个扩展,让它更像你想要的:

extension NSString {
    open func replacingOccurrences(of target: String, with replacement: String, options: NSString.CompareOptions = []) -> String {
        replacingOccurrences(of: target, with: replacement, options: options, range: self.range(of: String(self)))
    }
}

现在您的原始代码应该可以工作了。

于 2020-05-16T17:57:28.780 回答