前置き
個人的に業務や自作でアプリを作るたびに、何回も同じようなことを調べてExtension
を作成しているので、メモ書き程度に残しておきたかった。
String Extension Variables
【前後空白改行】
extension String {
var hasSpaceAndNewlines: Bool {
return self.isEmpty || self.trimmingCharacters(in: .whitespacesAndNewlines) != self
}
}
print("text".hasSpaceAndNewlines) // false 任意の文字
print("".hasSpaceAndNewlines) // true 空
print(" ".hasSpaceAndNewlines) // true 半角スペース
print(" ".hasSpaceAndNewlines) // true 全角スペース
print("\n".hasSpaceAndNewlines) // true 改行
print("\n\n".hasSpaceAndNewlines)// true 改行2回
.whitespacesAndNewlines
以外にもオプションが存在する。
【地域・言語】
extension String {
/// 言語設定が「英語」かどうか ※1
var isEnglish: Bool {
return self.hasPrefix("en")
}
/// 言語設定が「日本語」かどうか
var isJapanese: Bool {
return self.hasPrefix("ja")
}
/// 地域設定が「日本語」かどうか ※2
var isJapan: Bool {
return self.hasSuffix("JP")
}
}
/// ※1
print("ja".isJapanese) // true
print("ja-EN".isJapanese) // true
print("en-JP".isJapanese) // false
print("aja-EN".isJapanese) // false
/// ※2
print("ja".isJapan) // false
print("ja-EN".isJapan) // false
print("en-JP".isJapan) // true
print("aja-EN".isJapan) // false
Locale.preferredLanguages
で端末の表示言語を取得できるので、そちらを使っても良かったが、サーバーからくる言語判定をしたかったので、少し広めに使い勝手良くしました。
上記以外の言語・地域はお好みでExtension
に追加してくだしい。
【日本語判定】
extension String {
/// 「漢字」かどうか
var isKanji: Bool {
let range = "^[\u{3005}\u{3007}\u{303b}\u{3400}-\u{9fff}\u{f900}-\u{faff}\u{20000}-\u{2ffff}]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
/// 「ひらがな」かどうか
var isHiragana: Bool {
let range = "^[ぁ-ゞ]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
/// 「カタカナ」かどうか
var isKatakana: Bool {
let range = "^[ァ-ヾ]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
}
print("otoko".isKanji) // false
print("男".isKanji) // true
print("男otoko".isKanji) // false
長文や「ひらがな」「カタカナ」が入り混じる場合はrange
をがっちゃんこする必要があります。
【日本語変換】
extension String {
/// 「ひらがな」に変換 ※1
var toHiragana: String? {
return self.applyingTransform(.hiraganaToKatakana, reverse: false)
}
/// 「カタカナ」に変換
var toKatakana: String? {
return self.applyingTransform(.hiraganaToKatakana, reverse: true)
}
/// 「ひらがな」を含むかどうか ※2
var hasHiragana: Bool {
guard let hiragana = self.toKatakana else { return false }
return self != hiragana // 1文字でもカタカナに変換されている場合は含まれると断定できる
}
/// 「カタカナ」を含むかどうか
var hasKatakana: Bool {
guard let katakana = self.toHiragana else { return false }
return self != katakana // 1文字でもひらがなに変換されている場合は含まれると断定できる
}
}
/// ※1
print("hiragana".toHiragana) // optional("hiragana") 英語はそのまま
print("ひらがな".toHiragana) // optional("ひらがな") ひらがなはそのまま
print("ヒラガナ".toHiragana) // optional("ひらがな") 変換された
/// ※2
print("hiragana".hasHiragana) // false
print("ひらがな".hasHiragana) // true
print("ヒラガナ".hasHiragana) // false
print("hiraganaひらがなヒラガナ".hasHiragana) // true
applyingTransform
でサクッと作れる。.hiraganaToKatakana
以外にもオプションがあります。
単語や分に含まれるかどうかは、先ほどのNSPredicate
を使ったバリデーションでも含まれるかの判定を作れるが、長くなってしまうのでこちらで作る方が短くて完結かと。
【英語大文字小文字】
extension String {
/// 「小文字だけ」かどうか
var isLowrcased: Bool {
return self == self.lowercased()
}
/// 「大文字だけ」かどうか
var isUppercased: Bool {
return self == self.uppercased()
}
}
print("english".isLowrcased) // true
print("English".isLowrcased) // false
print("ひらがな".isLowrcased) // true ひらがなは変換されないのでtrueとなる
英語にしか使えないので、ちゃんと使いたい方はNSPredicate
でバリデーションしてくだしい。
【URL】
extension String {
var isUrl: Bool {
let linkValidation = NSTextCheckingResult.CheckingType.link.rawValue
guard let detector = try? NSDataDetector(types: linkValidation) else { return false }
let results = detector.matches(in: self, options: .reportCompletion, range: NSMakeRange(0, self.characters.count))
return results.first?.url != nil
}
}
print("http".isUrl) // false
print("https".isUrl) // false
print("http://".isUrl) // false
print("https://".isUrl) // false
print("http://a".isUrl) // true
print("https://a".isUrl) // true
デフォルトで画像の拡張子あたりまでバリデーションしてくれたら、なおよかったんですけど笑
参考に載せましたが、 NSTextCheckingResult
はPhoneNumber
,Address
とかもあります。
全部まとめたやつ
extension String {
/// 前後にスペース、改行があるかどうか
var hasSpaceAndNewlines: Bool {
return self.isEmpty || self.trimmingCharacters(in: .whitespacesAndNewlines).characters.isEmpty
}
/// 言語設定が「英語」かどうか
var isEnglish: Bool {
return self.hasPrefix("en")
}
/// 言語設定が「日本語」かどうか
var isJapanese: Bool {
return self.hasPrefix("ja")
}
/// 地域設定が「日本語」かどうか ※2
var isJapan: Bool {
return self.hasSuffix("JP")
}
/// 「漢字」かどうか
var isKanji: Bool {
let range = "^[\u{3005}\u{3007}\u{303b}\u{3400}-\u{9fff}\u{f900}-\u{faff}\u{20000}-\u{2ffff}]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
/// 「ひらがな」かどうか
var isHiragana: Bool {
let range = "^[ぁ-ゞ]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
/// 「カタカナ」かどうか
var isKatakana: Bool {
let range = "^[ァ-ヾ]+$"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
/// 「ひらがな」に変換 ※1
var toHiragana: String? {
return self.applyingTransform(.hiraganaToKatakana, reverse: false)
}
/// 「カタカナ」に変換
var toKatakana: String? {
return self.applyingTransform(.hiraganaToKatakana, reverse: true)
}
/// 「ひらがな」を含むかどうか ※2
var hasHiragana: Bool {
guard let hiragana = self.toKatakana else { return false }
return self != hiragana // 1文字でもカタカナに変換されている場合は含まれると断定できる
}
/// 「カタカナ」を含むかどうか
var hasKatakana: Bool {
guard let katakana = self.toHiragana else { return false }
return self != katakana // 1文字でもひらがなに変換されている場合は含まれると断定できる
}
/// 「小文字だけ」かどうか
var isLowrcased: Bool {
return self == self.lowercased()
}
/// 「大文字だけ」かどうか
var isUppercased: Bool {
return self == self.uppercased()
}
/// URLかどうか
var isUrl: Bool {
let linkValidation = NSTextCheckingResult.CheckingType.link.rawValue
guard let detector = try? NSDataDetector(types: linkValidation) else { return false }
let results = detector.matches(in: self, options: .reportCompletion, range: NSMakeRange(0, self.characters.count))
return results.first?.url != nil
}
}
あとがき
わりとピンポイントな使い所のものしかないので、「あ、これ!」みたいなやつはなかったかと思います。笑
今回は自分のプロジェクトの使い勝手が良いように作成しているので、上記はあくまでも指標程度に考えていただき、みなさんの使い勝手が良いように書き換えてくだされば、と思っております。
参考
言語・地域
ひらがな・カタカナ
- Swift3.0 で ひらがな <-> カタカナ 変換する
- [iOS][Swift]長いパターンの正規表現を扱う方法
- [Swift3]文字列が人名かどうかをバリデーションする方法
- Swiftで入力された文字をカタカナに変換して取得する
- 文字列を全角/半角に変換する
- 正規表現の使用方法
URL
その他
Phone and Address Validations