[Swift] String の位置指定を 理解する(String/String.Index と NSString/Int)
Sponsor Link
環境&対象
- macOS Monterey 13 Beta3
- Xcode 14.0 Beta3
- iOS 16.0 beta
部分文字列
文字列処理として、文字列の一部を抜き出したり、置き換えたりということをすることがあります。
そのような時に、変更対象である 文字列の一部を指定することが必要となります。
文字列中の範囲指定には、 String 向けには Range<String.Index> が、NSString 向けには、NSRange が使用されます。
部分抜き出し操作
文字列の部分文字列を抜き出すためには、開始位置と終了位置指定が必要です。
この開始位置(と終了位置指定)で、前回説明した、位置情報が使用されます。
Range は、開始/終了位置の情報が必要です。
NSRange には、開始位置と文字列長の情報が必要となります。
Range/NSRange
String/NSString の一部は、文字列中の範囲として表現され それぞれ Range/NSRange を使って指定することができます
Range
String の範囲を表現するためには Range<String.Index> が使用されます。
Range は、String 向けに特別に作られた型ではありません。
Apple のドキュメントは、こちら。
数学的にいうと、半開区間を表現するための型です。
例えば、Double を使って、0 から 10まで(ただし10を含まない)という範囲を表すには、Range 型を使用して、以下のように書きます。
数学的には [0,10) と書く区間を表しています。
let range: Range<Double> = 0..<10
range.contains(0) // -> true
range.contains(10) // -> false
この場合の半開区間とは、0 を含み、(10を含まない)直前までの区間ということです。
ですので、contains という Range に含まれるかを判定するメソッドの結果が、0 は true ですが、10 は false になっています。
このように、Range は、連続している要素の区間を表す型です。
文字列の Index も、(その文字列の文字にそって)連続していますので、文字列中の範囲を、この Range を使用して表現することができます。
なお、String 中の範囲を表現する時に Range が使用するのは、String.Index です。
ですので、String では、Range<String.Index> を使用して区間を表現します。
NSRange
NSString の範囲を指定するには、NSRange が使用されます。
Apple のドキュメントは、こちら。
NSRange として見つかるのは上記ですが、実際には、こちらを見る方がわかります。
NSRange は、位置情報と長さ情報を組み合わせて記録しています。
位置情報、長さ 共に、Int で指定します。
Range 的な、開始位置・終了位置という形での情報としては、lowerBound/upperBound というプロパティが用意されています。
lowerBound/upperBound を使用した initializer もあります。
なお、NSRange も NSString 専用ということではなく、連続した情報を表現することができます。区間の共通部分を計算したりということも可能です。
部分文字列関連操作
抜き出し
文字列から、その文字列の 一部文字列を抜き出す操作です。
“Hello world!” から “Hello” を抜き出したりということです。
String での部分文字列抜き出し
String は、subscript で Range を指定することで、指定範囲の文字列を抜き出すことができます。
Apple のドキュメントは、こちら。
let text: String = "012345"
let index1 = text.index(after: text.startIndex)
let index4 = text.index(text.startIndex, offsetBy: 4)
let substr = text[index1..<index4])
print(substr)
// print-out
123
NSString での部分文字列抜き出し
NSString では、substring というメソッドを使用して、NSRange 指定で部分文字列を抜き出します。
Apple のドキュメントは、こちら。
let nsStr: NSString = "012345"
let pos1 = 1
let nsSubstr = nsStr.substring(with: NSRange(location: pos1, length: 3))
print(nsSubstr)
// print-out
123
削除
文字列から指定範囲の文字列を削除することもできます。
“Hello world!” から “world” を削除して、”Hello !” としたりすることです。
String での部分文字列削除
String で 文字列の一部(部分文字列) を削除するには、removeSubrange メソッドを使います。
Apple のドキュメントは、こちら。
var text: String = "012345"
let index1 = text.index(after: text.startIndex)
let index4 = text.index(text.startIndex, offsetBy: 4)
text.removeSubrange(index1..<index4)
print(text)
// print-out
045
NSString での部分文字列削除
NSString で 文字列の一部を削除するには、NSMutableString の deleteCharacters(in:) メソッドを使います。
# NSString は、immutable つまり 変更できない文字列を表すオブジェクトなので、変更したければ NSMutableString を使う必要があります。
Apple のドキュメントは、こちら。
let nsStr: NSMutableString = "012345"
let nsRange = NSRange(location: 1, length: 3)
nsStr.deleteCharacters(in: nsRange)
print(nsStr)
// print-out
045
置き換え
指定範囲の文字列を 別の文字列に置き換える操作もあります。
String での部分文字列置き換え
String で 指定範囲の文字列を別の文字列に置き換えるには、replaceSubrange メソッドを使用します。
Apple のドキュメントは、こちら。
以下の例のように、置き換える長さは、置き換える文字列長と一致している必要はありません。
let text: String = "012345"
var text2 = text
let index1 = text2.index(after: text.startIndex)
let index4 = text2.index(text.startIndex, offsetBy: 4)
text2.replaceSubrange(index1..<index4, with: "Hello")
print(text2)
// print-out
0Hello45
NSString での部分文字列置き換え
NSString で 指定範囲の文字列を別の文字列に置き換えるには、replacingCharacters メソッドを使用します。
Apple のドキュメントは、こちら。
llet nsStr: NSMutableString = "012345"
let nsRange = NSRange(location: 1, length: 3)
nsStr.replaceCharacters(in: nsRange, with: "Hello")
print(nsStr)
// print-out
0Hello45
指定範囲長が0 のケース
replaceSubrange/ replaceCharacters で与えた範囲の長さが0の場合、単純に指定位置に文字列を挿入することになります。
var text: String = "012345"
let index1 = text.index(after: text.startIndex)
let index4 = text.index(index1, offsetBy: 0)
text.replaceSubrange(index1..<index4, with: "Hello")
print(text)
// print-out
0Hello12345
let nsStr: NSMutableString = "012345"
let nsRange = NSRange(location: 1, length: 0)
nsStr.replaceCharacters(in: nsRange, with: "Hello")
print(nsStr)
// print-out
0Hello12345
置き換え文字列が空文字のケース
replaceSubrange/ replaceCharacters で与えた置き換え文字列が 空文字(“”) である場合、単純に指定範囲が削除されることになります。
var text: String = "012345"
let index1 = text.index(after: text.startIndex)
let index4 = text.index(index1, offsetBy: 3)
text.replaceSubrange(index1..<index4, with: "")
print(text)
// print-out
045
let nsStr: NSMutableString = "012345"
let nsRange = NSRange(location: 1, length: 3)
nsStr.replaceCharacters(in: nsRange, with: "")
print(nsStr)
// print-out
045
まとめ
String と Range<String.Index>, NSString と NSRange を使った文字列中の範囲指定をまとめました。
- String は、Range<String.Index> を使って指定する
- NSString は、NSRange を使って指定する
- String には、Range を受け取るメソッドとして、subscript, replaceSubrange, removeSubrange が用意されている
- NSString/NSMutableString には、NSRange を受け取るメソッドとして、substring, replaceCharacters, deleteCharacters が用意されている
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link