Swiftでプログラミング。- 文字列と文字 2
Strings and Characters 文字列と文字
String Interpolation 文字列間挿入
文字列補間は、定数、変数、リテラル、および式の組み合わせから、それらの値を文字列リテラル内に含めることにより、新しい文字列値を構築する方法です。文字列間挿入は、単一行と複数行の両方の文字列リテラルで使用できます。文字列リテラルに挿入する各項目は、backslash(\)で始まる括弧のペアで囲まれます。
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
上記の例では、multiplierの値は\(multiplier)として文字列リテラルに挿入されます。このプレースホルダーは、実際の文字列を作成するために文字列補間が評価されるときに、乗数の実際の値に置き換えられます。
乗数の値も、文字列の後半にある大きな式の一部です。この式は、Double(multiplier)* 2.5の値を計算し、結果(7.5)を文字列に挿入します。この場合、式が文字列リテラル内に含まれていると、式は\(Double(multiplier)* 2.5)として記述されます。
拡張文字列区切り文字"#"を使用して、"文字列間挿入"を含む文字列を作成できます。例えば:
print(#"Write an interpolated string in Swift using \(multiplier)."#)
// Prints "Write an interpolated string in Swift using \(multiplier)."
拡張区切り文字を使用する文字列内で文字列間挿入を使用するには、backslash(\)の後の番号記号の数を、文字列の最初と最後の番号記号の数と一致させます。例えば:
print(#"6 times 7 is \#(6 * 7)."#)
// Prints "6 times 7 is 42."
挿入された文字列内の括弧内に書き込む式には、エスケープされていないbackslash(\)、キャリッジリターン、または改行を含めることはできません。ただし、他の文字列リテラルを含めることができます。
Unicode ユニコード
Unicodeは、テキストを処理するための国際標準のエンコーディングです。これにより、標準化された形式で任意の言語のほぼすべての文字が表示でき、テキストファイルやWebページなどの文字を読み書きできます。このセクションで説明するように、Swiftの文字列と文字はUnicode に準拠しています。
Unicode Scalar Values Unicodeスカラー値
Swift’s native String typeについてはUnicodeスカラー値からバックグラウンドで構築されています。 Unicodeスカラー値は、文字または修飾子の一意の21ビット数です。たとえば、LATIN SMALL LETTER A( "a")の場合はU + 0061、FRONT-FACING BABY CHICK( "🐥")の場合はU + 1F425です。
すべての21ビットUnicodeスカラー値が文字に割り当てられるわけではないことに注意してください。一部のスカラーは、将来の割り当てまたはUTF-16エンコーディングでの使用のために予約されています。文字に割り当てられたスカラー値には、通常、上記の例のLATIN SMALL LETTERAやFRONT-FACINGBABYCHICKなどの名前も付いています。
Extended Grapheme Clusters 拡張書記素クラスター
SwiftのCharacterタイプのすべてのインスタンスは、単一の拡張書記素クラスターを表します。拡張書記素クラスターは、1つ以上のUnicodeスカラーのシーケンスであり、(結合すると)1つの人間が読める文字を生成します。
書記素:書記言語において意味上の区別を可能にする最小の図形単位
例を示すと、文字éは、単一のUnicodeスカラーé(LATIN SMALL LETTER E WITH ACUTE、またはU + 00E9)として表すことができます。ただし、同じ文字をスカラーのペアとして表すこともできます。標準の文字e(LATIN SMALL LETTER E、またはU + 0065)の後に、COMBINING ACUTE ACCENTスカラー(U + 0301)が続きます。 COMBINING ACUTE ACCENTスカラーは、その前のスカラーにグラフィカルに適用され、Unicode対応のテキストレンダリングシステムによってレンダリングされるときにeをéに変換します。
どちらの場合も、文字éは、拡張された書記素クラスターを表す単一のSwift文字値として表されます。最初のケースでは、クラスターに単一のスカラーが含まれています。 2番目のケースでは、2つのスカラーのクラスターです。
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ́
// eAcute is é, combinedEAcute is é
拡張書記素クラスターは、多くの複雑なスクリプト文字を単一の文字値として表す柔軟な方法です。たとえば、韓国語のアルファベットのハングル音節は、合成済みまたは分解済みのシーケンスとして表すことができます。これらの表現は両方とも、Swiftでは単一の文字値として表すことができます。
let precomposed: Character = "\u{D55C}" // 한
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // ᄒ, ᅡ, ᆫ
// precomposed is 한, decomposed is 한
拡張書記素クラスターを使用すると、マークを囲むためのスカラー(COMBINING ENCLOSINGCIRCLEやU + 20DDなど)を使用して、他のUnicodeスカラーを単一の文字値の一部として囲むことができます。
let enclosedEAcute: Character = "\u{E9}\u{20DD}"
// enclosedEAcute is é⃝
地域インジケータシンボルのUnicodeスカラーをペアで組み合わせて、単一の文字値を作成できます。たとえば、地域インジケータ記号文字U(U + 1F1FA)と地域インジケータ記号文字S(U + 1F1F8)の組み合わせは次のとおりです。
let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"
// regionalIndicatorForUS is 🇺🇸
Counting Characters 文字を数える
文字列内の文字値のカウントを取得するには、文字列のcountプロパティを使用します。
let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"
Swiftが文字値に拡張書記素クラスターを使用しているということは、文字列の連結と変更が文字列の文字数に常に影響するとは限リません。
たとえば、新しい文字列を4文字の単語cafeで初期化し、文字列の最後にCOMBINING ACUTE ACCENT(U + 0301)を追加すると、結果の文字列の文字数は4のままになり、 eではなくéの4番目の文字の修飾となるので文字数は変わらない:
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafe is 4"
word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in café is 4"
拡張書記素クラスターは、複数のUnicodeスカラーで構成できます。つまり、異なる文字、および同じ文字の異なる表現は、格納するために異なる量のメモリを必要とする可能性があります。このため、Swiftの文字は、文字列の表現内でそれぞれ同じ量のメモリを使用するわけではありません。その結果、文字列内の文字数は、拡張された書記素クラスターの境界を決定するために文字列を反復処理せずに計算することはできません。特に長い文字列値を使用している場合は、その文字列の文字を決定するために、countプロパティが文字列全体のUnicodeスカラーを反復処理する必要があることに注意してください。
countプロパティによって返される文字の数は、同じ文字を含むNSStringのlengthプロパティと常に同じであるとは限りません。 NSStringの長さは、文字列内のUnicode拡張書記素クラスターの数ではなく、文字列のUTF-16表現内の16ビットコードユニットの数に基づいています。
この記事が気に入ったらサポートをしてみませんか?