mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-08-22 15:05:26 +00:00
118 lines
4.5 KiB
Swift
118 lines
4.5 KiB
Swift
//
|
||
// extension StringProtocol.swift
|
||
// Keyboard
|
||
//
|
||
// Created by ensan on 2020/10/16.
|
||
// Copyright © 2020 ensan. All rights reserved.
|
||
//
|
||
|
||
import Foundation
|
||
|
||
public extension StringProtocol {
|
||
/// ローマ字と数字のみかどうか
|
||
/// - note: 空文字列の場合`false`を返す。
|
||
@inlinable
|
||
var onlyRomanAlphabetOrNumber: Bool {
|
||
!isEmpty && range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil
|
||
}
|
||
/// ローマ字のみかどうか
|
||
/// - note: 空文字列の場合`false`を返す。
|
||
@inlinable
|
||
var onlyRomanAlphabet: Bool {
|
||
!isEmpty && range(of: "[^a-zA-Z]", options: .regularExpression) == nil
|
||
}
|
||
/// ローマ字を含むかどうか
|
||
/// - note: 空文字列の場合`false`を返す。
|
||
/// 以前は正規表現ベースで実装していたが、パフォーマンス上良くなかったので以下のような実装にしたところ40倍程度高速化した。
|
||
@inlinable
|
||
var containsRomanAlphabet: Bool {
|
||
for value in self.utf8 {
|
||
if (UInt8(ascii: "a") <= value && value <= UInt8(ascii: "z")) || (UInt8(ascii: "A") <= value && value <= UInt8(ascii: "Z")) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
/// 英語として許容可能な文字のみで構成されているか。
|
||
/// - note: 空文字列の場合`false`を返す。
|
||
@inlinable
|
||
var isEnglishSentence: Bool {
|
||
!isEmpty && range(of: "[^0-9a-zA-Z\n !'_<>\\[\\]{}*@`\\^|~=\"#$%&\\+\\(\\),\\-\\./:;?’\\\\]", options: .regularExpression) == nil
|
||
}
|
||
|
||
/// 仮名か
|
||
@inlinable
|
||
var isKana: Bool {
|
||
!isEmpty && range(of: "[^ぁ-ゖァ-ヶ]", options: .regularExpression) == nil
|
||
}
|
||
|
||
/// Returns a String value in which Hiraganas are all converted to Katakana.
|
||
/// - Returns: A String value in which Hiraganas are all converted to Katakana.
|
||
@inlinable func toKatakana() -> String {
|
||
// カタカナはutf16で常に2バイトなので、utf16単位で処理して良い
|
||
let result = self.utf16.map { scalar -> UInt16 in
|
||
if 0x3041 <= scalar && scalar <= 0x3096 {
|
||
return scalar + 96
|
||
} else {
|
||
return scalar
|
||
}
|
||
}
|
||
return String(utf16CodeUnits: result, count: result.count)
|
||
}
|
||
|
||
/// Returns a String value in which Katakana are all converted to Hiragana.
|
||
/// - Returns: A String value in which Katakana are all converted to Hiragana.
|
||
@inlinable func toHiragana() -> String {
|
||
// ひらがなはutf16で常に2バイトなので、utf16単位で処理して良い
|
||
let result = self.utf16.map { scalar -> UInt16 in
|
||
if 0x30A1 <= scalar && scalar <= 0x30F6 {
|
||
return scalar - 96
|
||
} else {
|
||
return scalar
|
||
}
|
||
}
|
||
return String(utf16CodeUnits: result, count: result.count)
|
||
}
|
||
|
||
/// Returns an Index value that is the specified distance from the start index.
|
||
/// - Parameter:
|
||
/// - offset: The distance to offset from the start index.
|
||
/// - Returns: An Index value that is the specified distance from the start index.
|
||
@inlinable
|
||
func indexFromStart(_ offset: Int) -> Index {
|
||
self.index(self.startIndex, offsetBy: offset)
|
||
}
|
||
|
||
// エスケープが必要なのは次の文字:
|
||
/*
|
||
\ -> \\
|
||
\0 -> \0
|
||
\n -> \n
|
||
\t -> \t
|
||
, -> \c
|
||
" -> \d
|
||
*/
|
||
// please use these letters in order to avoid user-inputting text crash
|
||
func escaped() -> String {
|
||
var result = self.replacingOccurrences(of: "\\", with: "\\b")
|
||
result = result.replacingOccurrences(of: "\0", with: "\\0")
|
||
result = result.replacingOccurrences(of: "\n", with: "\\n")
|
||
result = result.replacingOccurrences(of: "\t", with: "\\t")
|
||
result = result.replacingOccurrences(of: ",", with: "\\c")
|
||
result = result.replacingOccurrences(of: " ", with: "\\s")
|
||
result = result.replacingOccurrences(of: "\"", with: "\\d")
|
||
return result
|
||
}
|
||
|
||
func unescaped() -> String {
|
||
var result = self.replacingOccurrences(of: "\\d", with: "\"")
|
||
result = result.replacingOccurrences(of: "\\s", with: " ")
|
||
result = result.replacingOccurrences(of: "\\c", with: ",")
|
||
result = result.replacingOccurrences(of: "\\t", with: "\t")
|
||
result = result.replacingOccurrences(of: "\\n", with: "\n")
|
||
result = result.replacingOccurrences(of: "\\0", with: "\0")
|
||
result = result.replacingOccurrences(of: "\\b", with: "\\")
|
||
return result
|
||
}
|
||
}
|