🔖

文字列操作の方法とunicodeについて

3 min read 2

タイトルについて指摘があったため変更しました。

この記事では、文字列について解説していきます。

インデックスへのアクセス


配列と同じように[]を使ってアクセスできます。

無いものをを参照しようとすると、undefinedが返されます。


const str = "abcdefg";
// a
console.log(str[0], str[9]);
// undefined
console.log(str[9]);

文字列と文字コードについて


JavaScriptは、UTF-16を採用しています。

lengthプロパティは、Code Unitの個数を返します。

なので、絵文字や𩸽など一部の漢字は2文字と判定されてしまいます。

以下、JavaScript Primerより引用

JavaScriptには、文字列におけるCode Pointの個数を数えるメソッドは用意されていません。

これを行うには、文字列をCode Pointごとに区切った配列へ変換して、配列の長さを数えるのが簡潔です。

Array.fromメソッドは、引数にiterableなオブジェクトを受け取り、それを元にした新しい配列を返します。

しかし、Code Pointの数を数えた場合でも、直感的な結果にならない場合もあります。

なぜなら、Code Pointには制御文字などの視覚的に見えないものも定義されているためです。

そのため、文字として数えたくないものは無視するなど、視覚的な文字列の長さを数えるにはさらなる工夫が必要になります。

残念ながら、ビルトインメソッドにはこれらを簡単に扱う方法は用意されていません。

for...ofによる反復処理も文字列をCode Pointごとに扱えます。 これは、for...of文が対象をIteratorとして列挙するためです。

このように、文字列を扱うときは文字コードについても意識しておく必要があります。


const alph = "a";
const pic = "☺️";
const kanji = "𩸽";

// 1
console.log(alph.length);
// 2
console.log(pic.length);
// 2
console.log(kanji.length);

ちなみに、lengthになぜ()が必要無いのかというと、メソッドではなくプロパティであるためです。

分割と結合


Split join

splitメソッドで文字列の分割をすることができます。

逆に、結合はjoinメソッドを使ってすることができます。


const tel = "090-2900-5633";
const arr = tel.split("-");

// ["090", "2900", "5633"]
console.log(arr);
// "090-2900-5633"
console.log(arr.join("-"));

slice subString

sliceメソッドとsubStringメソッドを使うことで文字列から値の抽出をすることができます。

基本的に、配列に使ったsliceと同じ使い方で、最初と最後の位置を引数として持たせる形になります。

引数が1つの場合はそこから最後までの値を抽出し、sliceで引数がマイナスの場合は後ろから数えた値になります。


const str = "abcdefg";

// bcdefg
console.log(str.slice(1));
// bcde
console.log(str.slice(1, 5));
// ""
console.log(str.slice(5, 1));
// g
console.log(str.slice(-1));
// bcdefg
console.log(str.substring(1));
// bcde
console.log(str.substring(1, 5));
// bcde
console.log(str.substring(5, 1));
// abcdefg
console.log(str.substring(-1));

subStringメソッドは、マイナスの値を指定した場合は常に0として扱われます。

また、第一引数の位置が第二引数の位置より大きい場合、第一引数と第二引数が入れ替わるという挙動になります。

なので、sliceを使う方が無難かと。

検索


文字列の検索をしたい場合は、配列と同じでindexOfが使えます。

単純に存在の有無を確認したい場合は、

  • startsWith ⇨ その文字で始まるかを判定
  • endsWith ⇨ その文字で終わるかを判定
  • Includes ⇨ その文字を含んでいるか判定

を使用すると良いです。


const str = "abcdefg";

// 2
console.log(str.indexOf("c"));
// true
console.log(str.startsWith("a"));
// false
console.log(str.startsWith("c"));
// true
console.log(str.endsWith("g"));
// false
console.log(str.endsWith("a"));
// true
console.log(str.includes("a"));
// false
console.log(str.includes("h"));


削除・置換


文字列の一部を置換したり削除するにはreplaceメソッドが使えます。

また、全ての対象の文字を置換したい時はreplaceAllメソッドが使えます。


const str = "abcabcabc";
 
// abcabcabc
console.log(str.replace("a", "d"));
// dbcdbcdbc
console.log(str.replaceAll("a", "d"));
// bcbcbc
console.log(str.replaceAll("a", ""));
// abcabcabc
console.log(str);

ちなみに、これらは非破壊的メソッドなので、元の文字列に影響なく使えます。

おわりに


さて、今回は文字列の操作などについて解説してきました。

どこか参考になる所はありましたか?

もし、少しでも参考になったら良いねを押していただけると今後の励みになります。

また、僕のブログではReactエンジニアになるためのロードマップを無料で全て公開しているので、参考にどうぞ。バックエンドエンジニアを目指している方などにも役立つ情報を書いてます。

https://hinoshin-blog.com/react-roadmap/

おわり

Discussion

ちなみに、lengthになぜ()が必要無いのかというと、メソッドではなくプロパティであるためです。
なので、str.length = 0 のようにして文字サイズを変えることができるという訳です。

配列とは違い、文字列は長さを変えることは出来ないです。JavaScript において文字列はプリミティブで、イミュータブルです。

https://developer.mozilla.org/ja/docs/Glossary/Primitive

ちなみに、これらは非破壊的メソッドなので、元の文字列に影響なく使えます。

正しいのですが、そもそもプリミティブに破壊的メソッドはないと理解する方が汎用的に使える知識になるのではないかなと思います。


これ以降の指摘は完全にお節介にあたるかもしれませんが指摘させてください。

特に意味なく「科学」という言葉を使われているとおっしゃっていますが、対象としていない読者を呼び込んでしまう可能性があるかなと思いました。以下の記事が参考になるかもしれません。

https://zenn.dev/uhyo/articles/technical-articles

情報のアウトプットは素晴らしいことですので、これからもぜひ続けていってください!

ご指摘ありがとうございます!!
問題の箇所は修正しておきました。

ログインするとコメントできます