【STEP.18】
JavaScriptの文字列操作をマスターしよう!

Stringオブジェクトとは

Stringオブジェクトは、文字列型(String型)の値を扱うためのラッパーオブジェクトです。

文字列の抽出や加工、検索などを行うための機能を提供します。

Stringオブジェクトのメンバー一覧

Stringオブジェクトで利用可能な主なメンバーは、以下の表の通りです。

【Stringオブジェクトの主なメンバー(*は静的メソッド)】
分類メンバー概要
検索indexOf(search [,from])文字列前方(from文字目)から部分文字列searchを検索(先頭文字を0文字目と数える)
lastIndexOf(search [,from])文字列後方(from文字目)から部分文字列searchを検索(先頭文字を0文字目と数える)
includes(str [,pos])
ES2015
文字列が部分文字列strを含んでいるか
(引数posは検索開始位置)
startsWith(str [,pos])
ES2015
文字列が部分文字列strで始まるか
(引数posは検索開始位置)
endsWith(str [,len])
ES2015
文字列が部分文字列strで終わるか
(引数lenは文字列長)
部分文字列substring(start [,end])文字列からstart~end-1文字目を取得
(先頭文字を0文字目と数える)
slice(start [,end])文字列からstart~end-1文字目を取得
(先頭文字を0文字目と数える)
substr(start [,cnt])文字列のstart文字目からcnt文字を取得
(先頭文字を0文字目と数える)
charAt(n)文字列からn番目の文字を取得
(先頭文字を0文字目と数える)
split(separator [,limit])文字列を区切り文字separatorで分割し、その結果を配列として取得(引数limitは分割の最大数)
正規表現match(reg)正規表現regで文字列を検索、合致した部分文字列を取得
replace(reg, rep)正規表現regで文字列を検索、合致した部分を部分文字列repで置換
search(reg)正規表現regで文字列を検索、一致する最初の文字位置を取得
大文字小文字toLowerCase()小文字に変換
toUpperCase()大文字に変換
ド変換charCodeAt(n)n番目の文字をLatin-1コードに変換
(先頭文字を0文字目と数える)
*fromCharCode(c1,c2,…)Latin-1コードc1,c2…
codePointAt(n)
ES2015
n番目の文字をUTF-16エンコードされたコードポイント値に変換(先頭文字を0文字目と数える)
*fromCodePoint(num,…)
ES2015
コードポイント値から文字列を生成
その他concat(string)文字列の後方に文字列stringを連結
trim()文字列の前後から空白を削除
length文字列の長さを取得
repeat(count)
ES2015
文字列をcount回だけ繰り返したものを取得
*raw`str`
ES2015
テンプレート文字列の生の文字列を取得
normalize([form])
ES2015
文字列を引数formの形式で正規化(引数formの値は、NFC、NFD、NFKCなど)
padStart(len [,pad])
ES2017
文字列が指定長lenになるように文字列の前方を任意の文字padで捕捉する
padEnd(len [,pad])
ES2017
文字列が指定長lenになるように文字列の後方を任意の文字padで捕捉する
trimStart()
ES2019
文字列の先頭から空白を除去
trimEnd()
ES2019
文字列の末尾から空白を除去

stringオブジェクトのメンバー一覧

正規表現に関するメソッドに関しては以下のページで詳しく解説しています。

特定の文字列を検索する【indexOf/lastIndexOf】

indexOflastIndexOfメソッドを利用します。

indexOf / lastIndexOfメソッド
str.indexOf(search [,from])
str.lastIndexOf(search [,from])
search   検索文字列
from     検索開始位置

indexOfメソッドは文字列の先頭から、lastIndexOfメソッドは後方から検索を開始するという違いがあります。

引数fromは、いずれも先頭からの文字数で指定します。

戻り値は見つかった文字位置(先頭文字は0)で、指定の文字列が見つからなかった場合には「-1」を返します。

let str = 'もももすももも';

console.log(str.indexOf('もも'));
// 結果:0
console.log(str.lastIndexOf('もも'));
// 結果:5
console.log(str.indexOf('もも',2));
// 結果:4
console.log(str.lastIndexOf('もも',2));
// 結果:1
console.log(str.indexOf('ももかん'));
// 結果:-1

文字列に特定の文字列が含まれているかを判定する【includes/startsWith/endsWith】

文字列に特定の文字列が含まれているかどうかを判定するには、次に掲げる表のようなメソッドを利用します。

【部分文字列の有無を判定するためのメソッド
(引数posは検索開始位置、lenは文字列長)】
メソッド概要
includes(str [,pos])文字列が部分文字列strを含んでいるか
startsWith(str [,pos])文字列が部分文字列strで始まるか
endsWith(str [,len])文字列が部分文字列strで終わるか

いわゆるincludesが部分一致検索、startsWithendsWithが前方/後方一致検索の役割を担います。

引数posで検索開始位置を指定することも可能です。

endsWithメソッドは、指定された引数lenを文字列長としたときの末尾を判定します。

let str = 'なまむぎなまごめなまたまご';

console.log(str.includes('なま'));
// 結果:true
console.log(str.startsWith('なま'));
// 結果:true
console.log(str.endsWith('なま'));
// 結果:false
console.log(str.includes('なま',6));
// 結果:true
console.log(str.startsWith('なま',2));
// 結果:false
console.log(str.endsWith('なま',2));
// 結果:true

部分文字列の有無を判定するだけでなく、登場位置を知りたい場合には、indexOflastIndexOfメソッドを利用します。

文字列から部分文字列を取り出す【substring/slice/substr/charAt】

Stringオブジェクトには、部分文字列を取り出すためのメソッドとして、次に掲げる表のようなメソッドが用意されています。

【部分文字列を取得するためのメソッド(先頭文字を0文字目と数える)】
メソッド概要
substring(start [,end])文字列からstart~end-1文字目を取得
slice(start [,end])文字列からstart~end-1文字目を取得
substr(start [,cnt])文字列のstart文字目からcnt文字を取得
charAt(n)文字列からn番目の文字を取得

substringsliceメソッドが文字列範囲(開始から終了)で部分文字列を抽出するのに対して、substrメソッドは開始位置 + 文字数で抽出します。

特定の1文字だけを取得したいならばcharAtメソッドを利用します。

let str ='こんにちは、あかちゃん';

console.log(str.substring(6));
// 結果:あかちゃん
console.log(str.substring(6,8));
// 結果:あか
console.log(str.slice(6,8));
// 結果:あか
console.log(str.substr(6,2));
// 結果:あか
console.log(str.charAt(6));
// 結果:あ

部分文字列を取得するメソッド

substringsliceメソッドの違いについては、特殊な例を確認する必要があります。

substringとsliceメソッドの違い

引数start > endである場合

この場合、substringメソッドは引数startendの位置を入れ替えて、部分文字列の抽出を試みます。

対して、sliceメソッドは入れ替えを行いませんので、結果は空文字列となります。

let str ='こんにちは、あかちゃん';

console.log(str.substring(8,6));
// 結果:あか 
console.log(str.slice(8,6));
// 結果:(空文字列)

引数start/endが負数である場合

この場合、substringメソッドは無条件にゼロと見なすのに対して、sliceメソッドは文字列末尾からの文字数と見なします。

let str ='こんにちは、あかちゃん';

console.log(str.substring(6,-3));
// 結果:こんにちは、
console.log(str.slice(6,-3));
// 結果:あか

上の例であれば、substringメソッドは引数の「-3」を「0」に変換し、さらに「引数start > endである場合」のルールに従って引数を逆転させた結果、「substring(0,6)」と見なします。

対して、sliceメソッドは引数の「-3」を後方からの文字数と見なしますので、「slice(6,8)」と同じ意味です。

文字列を分割文字列で分割し、その結果を配列として取得する【split】

splitメソッドを利用します。

splitメソッド
str.split([separator [,limit]])
separator  区切り文字
limit      分割の最大数

まずは、具体的な例を見てみましょう。

console.log('Java Script\nスクリプト言語'.split(/[\s\n]/));
console.log('Java Scriptはスクリプト言語'.split('は'));
console.log('Java Script'.split(''));
console.log('Java Script'.split());
console.log('Java Script\nスクリプト言語'.split(/[\s\n]/,2));
["Java", "Script", "スクリプト言語"]
["Java Script", "スクリプト言語"]
["J", "a", "v", "a", " ", "S", "c", "r", "i", "p", "t"]
["Java Script"]
["Java", "Script"]

引数separatorには、正規表現(.split(/[\s\n]/))、文字列(.split('は'))、いずれを利用しても構いません。

replaceメソッドと異なり、gオプションの有無に関わらず、splitメソッドは文字列全体を分割の対象とします。

引数separatorが空文字列の場合(.split(''))、splitメソッドは文字列を文字配列に変換します。

ただし、引数separatorを省略した場合(.split())には戻り値は元の文字列を1つだけ含んだ配列となります。

紛らわしい点なので、注意が必要です。

.split(/[\s\n]/,2)」は、引数limitを指定した場合です。

この場合、splitメソッドは引数limitを上限に文字列を分割します。

上限を超えた部分の文字列は切り捨てられます。

区切り文字を結果に含める場合

splitメソッドは、既定で結果に区切り文字を含めません。

区切り文字を結果にも反映させたい場合には、引数separatorに「(...)」でグループを含めるようにします。

(...)」にマッチした文字列は、結果配列にも反映されます。

たとえば以下は数値で文字列を分割する例です。

区切り文字となった数値も含まれる点に注目です。

let str = '桃栗3年柿8年';
console.log(str.split(/(\d)/));
// 結果:["桃栗", "3", "年柿", "8", "年"]

大文字⇔小文字を変換する【toLowerCase/toUpperCase】

toLowerCasetoUpperCaseメソッドを利用します。

let str ='JavaScript';
console.log(str.toLowerCase());
// 結果:javascript
console.log(str.toUpperCase());
// 結果:JAVASCRIPT

個別の地域にも対応したtoLocaleLowerCasetoLocaleUpperCaseメソッドもあります。

文字⇔Latin-1コードを変換する【charCodeAt/fromCharCode】

文字⇔Latin-1コードを変換するには、次に掲げる表のようなメソッドを利用します。

【文字⇔Latin-1コードを変換するためのメソッド(*は静的メソッド)】
メソッド概要
charCodeAt(n)n番目の文字をLatin-1コードに変換
(先頭文字を0文字目と数える)
*fromCharCode(c1,c2,…)Latin-1コードc1,c2…

具体例を見てみましょう。

let str = 'apple';
console.log(str.charCodeAt(0));
// 結果:97

console.log(String.fromCharCode(97));
// 結果:a

文字⇔コードポイント値を変換する【codePointAt/fromCodePoint】

文字⇔コードポイント値を変換するには、次に掲げる表のようなメソッドを利用します。

【文字⇔コードポイント値を変換するためのメソッド(*は静的メソッド)】
メソッド概要
codePointAt(n)
ES2015
n番目の文字をUTF-16エンコードされたコードポイント値に変換(先頭文字を0文字目と数える)
*fromCodePoint(num,…)
ES2015
コードポイント値から文字列を生成

具体例を見てみましょう。

let str = 'apple';
console.log(str.codePointAt(0));
// 結果:97

console.log(String.fromCodePoint(97));
// 結果:a

文字列の後方に文字列を連結する【concat】

concatメソッドを利用します。

concatメソッド
str.concat(string)
string    連結する文字列

具体例を見てみましょう。

let str = 'win';
console.log(str.concat('dow'));
// 結果:window

文字列前後の空白を除去する【trim】

trimメソッドを利用します。

ここでいう空白には、半角スペースだけでなく改行文字(\n)、タブ文字(\t)も含まれます。

trimメソッド

全角空白については、ブラウザーの種類/バージョンによっては除去しないものもあるので、注意が必要です。

文字列の長さを取得する【lengthプロパティ】

lengthプロパティを利用します。

let str1 = 'ともだち';
let str2 = '𠮟られて';
console.log(str1.length);
// 結果:4
console.log(str2.length);
// 結果:5

日本語(マルチバイト文字)も、基本的には1文字として認識されます。

ただし、例外がある点に注意が必要です。

たとえば、「
let str2 = '𠮟られて'
」のようなケースです。

見た目の文字数は4文字ですが、lengthプロパティの戻り値は1文字増えて5文字が返されます。

これは「𠮟」という字がサロゲートペアという特殊な文字であることから生じる問題です。

Unicodeではほとんどの文字を1文字2byteで表現します。

しかし、サロゲートペアは例外的に1文字4byteで表されており、これをJavaScriptでは2文字と見なしてしまうのです。

そこでサロゲートペアを含んだ文字列を正確にカウントするには、以下のようなコードを記述する必要があります。

let str = '𠮟られて';
let len = str.length;
let snum = str.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length - 1;
console.log(len - snum);
// 結果:4

[\uD800-\uDBFF][\uDC00-\uDFFF]」は、それぞれサロゲートペアを構成する上位/下位サロゲートを表します。

これに合致する文字で文字列を区切ることで、サロゲートペアの個数を求めています。

あとは、その値をlengthプロパティから引いてやることで、本来の文字数を求めることができます。

MEMO
サロゲートペアとは
2byteで表現できる文字数は65535文字です。

しかし、Unicodeで扱う文字が増えるにつれて、これでは不足する状況が出てきました。

そこで、一部の文字を4byteで表すことで、表現可能な文字数を拡張することとなりました。

これがサロゲートペアの意味です。

ES2015以降の環境を前提とするならば、演算子(スプレッド演算子)を利用することもできます。

console.log([...'𠮟られて'].length);
// 結果:4

演算子は、文字列を文字配列に分解します。

この際、サロゲートペアも正しく1文字として認識してくれるので、あとはできた配列のlengthプロパティを参照することで文字数を求めることができます。

文字列をn回繰り返したものを生成する【repeat】

repeatメソッドを利用します。

repeatメソッド
str.repeat(count)
count  回数

引数countには、0以上の値を指定できます。

0の場合は空文字列を返しますし、2.5のような小数では整数に丸めた結果(ここでは2)を使って処理します。

let str = 'じゅげむ';
	
console.log(str.repeat(3));
// 結果:じゅげむじゅげむじゅげむ
console.log(str.repeat(0));
// 結果:(空文字列)
console.log(str.repeat(2.5));
// 結果:じゅげむじゅげむ
console.log(str.repeat(-2));
// 結果:エラー(負数は不可)

文字列が指定長になるように任意の文字で捕捉する【padStart/padEnd】

padStartpadEndメソッドを利用します。

padStart/padEndメソッド
str.padStart(len [,pad])
str.padEnd(len [,pad])
len   延長後の文字列長
pad   補足する文字(既定は半角スペース)

padStartメソッドは文字列の前方、padEndメソッドは後方に、それぞれ最終的な文字列長がlenになるよう、文字(引数pad)を追加します。

let str = 'JavaScript';

console.log(str.padStart(15));
// 結果:     JavaScript
console.log(str.padStart(15,'*'));
// 結果:*****JavaScript
console.log(str.padEnd(15,'*'));
// 結果:JavaScript*****

文字列の先頭/末尾から空白を除去する【trimStart/trimEnd】

文字列の先頭/末尾から空白を除去するには、次に掲げるメソッドを利用します。

【文字列の先頭/末尾から空白を除去するメソッド】
メソッド概要
trimStart()文字列の先頭から空白を除去する
trimEnd()文字列の末尾から空白を除去する

具体例を見てみましょう。

trimStart/trimEndメソッド


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です