BPSの福岡拠点として一緒にお仕事をさせていただいています、株式会社ウイングドアの岡です。
今回、Swiftでの文字列置換についてご紹介したいと思います。
文字列内でマッチした部分文字列が、正しく置換できるようになることを
目的にやっていきたいと思います。
Swiftで文字列置換させようとしている方へ少しだけでも、
アドバイスになれば、うれしいです。
今回使用したバーションはSwift 5になります。
Rubyでの文字列置換
はじめに、Rubyでの文字列置換を見ていきましょう。
sub
メソッドを使った方法とgsub
メソッドになります。
irb(main):022:0> irb(main):023:0> hogehoge = "ああいうああえお"
=> "ああいうああえお"
irb(main):026:0> hogehoge.sub("ああ","あか")
=> "あかいうああえお"
sub
メソッドはマッチした最初の文字のみを置き換えた状態で文字列を生成して返します。
irb(main):005:0> hogehoge = "ああいうああえお"
=> "ああいうああえお"
irb(main):006:0> hogehoge.gsub("ああ","あか")
=> "あかいうあかえお"
gsub
メソッドはマッチする部分全てを置き換えた状態で文字列を生成して返します。
Swiftでの文字列置換
replaceSubrangeでの方法
後々、何かと便利なのでStringを拡張して実装してみました。
まず、range
メソッドで文字列中に置換したい文字があるかを
検索し文字列が見つかった場合は、Range
型で一致した文字位置が返ってくるので
replaceSubrange
メソッドで返ってきた文字位置に置換後の文字を入れ替えてます。
破壊的メソッドなので使用には注意して使う必要があるかと思います。
extension String {
func replace(_ from: String,_ to: String) -> String {
var replacedString = self
if let range = replacedString.range(of: from) {
replacedString.replaceSubrange(range, with: to)
}
return replacedString
}
}
では、実際に確認してみましょう。
var hogehoge = "ああいうああえお"
print(hogehoge.replace("ああ","あか"))
> あかいうああえお
置換自体はできてますが、ヒットした文字の最初だけしか、置換されてないようです。
ヒットした文字が、全て置換されるようにする必要がありますね。
複数の文字を置換できるように変更後
extension String {
func replace(_ from: String,_ to: String) -> String {
var replacedString = self
while((replacedString.range(of: from)) != nil){
if let range = replacedString.range(of: from) {
replacedString.replaceSubrange(range, with: to)
}
}
return replacedString
}
}
ループさせ置換対象の文字がヒットされるまで繰り返すよう変更してみました。
ヒットした文字が、全て置換されるか試してみましょう。
var hogehoge = "ああいうああえお"
print(hogehoge.replace("ああ","あか"))
> あかいうあかえお
ちゃんと置換されてますね。と思ったのですが、
文字列の置換中にrange
での検索で無限にヒットしている場合が判明。
var hogehoge = "あいうえお"
print(hogehoge.replace("あ", "あか"))
print(hogehoge.replace("あ", "あ"))
> 無限ループしてしまう
これだとダメなので別の方法で解決する必要がありますね。
replacingOccurrencesでの実装
公式ドキュメントを調べていくとreplacingOccurrences
というメソッドでも置換できるという
ことが分かり試しに実装してみました。
同じようにStringを拡張して使いやすいようにしてみました。
replacingOccurrences
は非破壊的メソッドになります。
extension String {
func replace(_ from: String,_ to: String) -> String {
var replacedString = self
replacedString = replacedString.replacingOccurrences(of: from, with: to)
return replacedString
}
}
試してみましょう。
var hogehoge = "ああいうああえお"
print(hogehoge.replace("ああ","あか"))
> あかいうあかえお
var hogehoge = "あいうえお"
print(hogehoge.replace("あ", "あか"))
print(hogehoge.replace("あ", "あ"))
> あかいうえお
> あいうえお
目的通り、複数文字列が置換され、同じ文字があっても正しく置換されました。
まとめ
Swiftを使った文字列置換について紹介しました。
今回は、replacingOccurrences
を使い解決しましたが
用途ごとに、分けて使う必要があるかと思いました。
参考に、公式ドキュメントを貼っておきましたので
使用する際は確認して使ってみてください。
株式会社ウイングドアでは、Ruby on RailsやPHPを活用したwebサービス、webサイト制作を中心に、
スマホアプリや業務系システムなど様々なシステム開発を承っています。