NSScannerクラスをSwift2.1で少し使ってみました2
NSScannerクラスをSwift2.1で少し使ってみました - 使って創ってAppの続きです。
NSScannerクラスをもう少し使ってみましょう。
下記のサイトを参考にしました。
実行環境
- Swift 2.1.1
空白スペースと改行はスキャンが続行される
スキャンに指定した文字列と違う文字列をスキャンしても、その文字列をスキップしてスキャンを続行することができます。デフォルトでは、空白スペースと改行がスキップされます。検索対象を空白スペースや改行にすると、それらを検索してくれます。
let source = " \n \n\n This is a pen."
let scanner = NSScanner(string: source)
var result: NSString?
scanner.scanString("This", intoString: &result)
print(result!)
// This
let scanner = NSScanner(string: source)
var result: NSString?
scanner.scanString("This", intoString: &result)
print(result!)
// This
検索対象から特定の文字を除外する
カンマ・空白スペース・改行をスキップしてスキャンするようにしてみます。
let skipset = NSMutableCharacterSet.whitespaceAndNewlineCharacterSet()
skipset.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let theScanner = NSScanner(string: ",,,\n,, , This is a pen.")
theScanner.charactersToBeSkipped = skipset
var result: NSString?
theScanner.scanString("This", intoString: &result)
print(result!)
// This
skipset.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let theScanner = NSScanner(string: ",,,\n,, , This is a pen.")
theScanner.charactersToBeSkipped = skipset
var result: NSString?
theScanner.scanString("This", intoString: &result)
print(result!)
// This
カンマ空白スペース区切りの文字列を、カンマ区切りで分割する
コードはこんな感じ。
let whitespaceAndPunctuationSet = NSMutableCharacterSet.whitespaceCharacterSet()
whitespaceAndPunctuationSet.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let theScanner = NSScanner(string: "Takeda, Oda, Tyousokabe, Uesugi")
theScanner.charactersToBeSkipped = whitespaceAndPunctuationSet
var name: NSString?
while theScanner.scanUpToString(",", intoString: &name) {
print(name!)
}
// Takeda
// Oda
// Tyousokabe
// Uesugi
whitespaceAndPunctuationSet.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let theScanner = NSScanner(string: "Takeda, Oda, Tyousokabe, Uesugi")
theScanner.charactersToBeSkipped = whitespaceAndPunctuationSet
var name: NSString?
while theScanner.scanUpToString(",", intoString: &name) {
print(name!)
}
// Takeda
// Oda
// Tyousokabe
// Uesugi
カンマ・空白スペース・改行をスキップ対象にしています。scanUpToStringメソッドでカンマを指定してるので、カンマが見つかった場合のスキャン開始位置がカンマになりそうですが、カンマはスキップ対象なのでスキャン開始位置になりません。今回の場合、一つ目のカンマを見つけた後のスキャン開始位置は Oda の O です。
もう少し難しい文字列をスキャンする
名前と年齢が name:~~ age:~~で書かれ、カンマで区切られる文字列をスキャンします。名前と年齢を抽出します。
let busyous = "name:武田 age:25, name:上杉 age:24, name:織田 age:56"
let whiteSpaceAndCommaCharset = NSMutableCharacterSet.whitespaceCharacterSet()
whiteSpaceAndCommaCharset.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let scanner = NSScanner(string: busyous)
scanner.charactersToBeSkipped = whiteSpaceAndCommaCharset
var busyoName: NSString?, busyoAge: Int32 = 0
while !scanner.atEnd {
scanner.scanString("name:", intoString: nil)
scanner.scanUpToString(" ", intoString: &busyoName)
scanner.scanString("age:", intoString: nil)
scanner.scanInt(&busyoAge)
print("拙者、\(busyoName!)と申す。齢\(busyoAge)なり。")
}
// 拙者、武田と申す。齢25なり。
// 拙者、上杉と申す。齢24なり。
// 拙者、織田と申す。齢56なり。
let whiteSpaceAndCommaCharset = NSMutableCharacterSet.whitespaceCharacterSet()
whiteSpaceAndCommaCharset.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ","))
let scanner = NSScanner(string: busyous)
scanner.charactersToBeSkipped = whiteSpaceAndCommaCharset
var busyoName: NSString?, busyoAge: Int32 = 0
while !scanner.atEnd {
scanner.scanString("name:", intoString: nil)
scanner.scanUpToString(" ", intoString: &busyoName)
scanner.scanString("age:", intoString: nil)
scanner.scanInt(&busyoAge)
print("拙者、\(busyoName!)と申す。齢\(busyoAge)なり。")
}
// 拙者、武田と申す。齢25なり。
// 拙者、上杉と申す。齢24なり。
// 拙者、織田と申す。齢56なり。
まとめ
- NSScannerクラスは、文字列を初めから終わりまで順番にスキャンする
- スキャン開始位置や、検索対象から特定の文字列を含めないようにできる
スキャン開始位置を頭で追うことが、このクラスを使うのに重要なことだなと感じました。