JavaScriptの学習・参考リファレンス/ドキュメント

JavaScript、ECMAScriptの学習と参考メモ 入門~初心者~中級者~上級者を目指して

String 文字列

JavaScriptの文字列型Stringについての説明です。

基本的な使い方

宣言

let str1 = 'abc';
let str2 = "abc";
let str3 = `abc`;
let str4 = String('abc');
let str5 = new String('abc');
let strLong1 = 'aaaaa bbbbb ccccc ddddd eeeee ' +
    'fffff ggggg hhhhh iiiii jjjjj ' +
    'kkkkk lllll mmmmm nnnnn oooo';
let strLong2 = 'aaaaa bbbbb ccccc ddddd eeeee \
fffff ggggg hhhhh iiiii jjjjj \
kkkkk lllll mmmmm nnnnn oooo';
let strLong3 = `aaaaa bbbbb ccccc ddddd eeeee
fffff ggggg hhhhh iiiii jjjjj
kkkkk lllll mmmmm nnnnn oooo`;

テンプレート文字列 (フォーマットした文字列)

const i = 10;
const str = `abc ${i} def ${i+1} g`;
console.log(str); // "abc 10 def 11 g"

文字の長さ

let str = 'abc';
let size = str.length;

個々の文字へのアクセス

let str = 'abc';

for (let i = 0; i < str.length; i++){
  console.log(str[i]); // "a", "b", "c"
}

for (let s of str){
  console.log(s); // "a", "b", "c"
}

for (let i in str){
  console.log(str[i]); // "a", "b", "c"
}

for (let i = 0; i < str.length; i++){
  console.log(str.charAt(i)); // "a", "b", "c"
}

エスケープ文字

console.log('\''); // 単一引用符
console.log('\"'); // 二重引用符
console.log('\\'); // バックスラッシュ、円マーク
console.log('\n'); // 改行
console.log('\r'); // 復帰
console.log('\v'); // 垂直タブ
console.log('\t'); // 水平タブ
console.log('\b'); // バックスペース
console.log('\f'); // ページ送り
console.log('\101'); // A U+0041
console.log('\u0041'); // A U+0041
console.log('\u{0041}'); // A U+0041
console.log('\x41'); // A U+0041

Stringのメソッド

位置の取得

位置が見つからない場合「-1」が返却される。

let str = 'abcdeabcde'

// 左から検索し指定した文字列が最初に見つかった位置(先頭が0)を取得
console.log(str.indexOf('cd')); // 2
// 第2引数で検索を始める位置を指定できます
console.log(str.indexOf('cd',3)); // 7

// 右から検索し指定した文字列が最初に見つかった位置(先頭が0)を取得
console.log(str.lastIndexOf('cd')); // 7
// こちらも第2引数で検索を始める位置を指定できます
console.log(str.lastIndexOf('cd',5)); // 2

比較

// 辞書的な順番で大小関係を比較する
console.log('a'.localeCompare('b')); // マイナスの値 'a' < 'b'
console.log('a'.localeCompare('a')); // 0  'a' = 'b'
console.log('b'.localeCompare('a')); // プラスの値  'a' > 'b'
console.log('2'.localeCompare('5')); // マイナスの値  '2' < '5'
console.log('2'.localeCompare('10')); // プラスの値  '2' > '10'

// 数値として大小関係を比較する
console.log('2'.localeCompare('10', undefined, {numeric: true})); // マイナスの値  '2' < '5'

文字列に関する判定

// 指定した文字列で開始しているかの判定
console.log('abcde'.startsWith('ab')); // true
console.log('abcde'.startsWith('cd')); // false
// 第2引数で検索を開始する位置を指定できる
console.log('abcde'.startsWith('cd',2)); // true

// 指定した文字列で終了しているかの判定
console.log('abcde'.endsWith('de')); // true
console.log('abcde'.endsWith('bc')); // false
// 第2引数で検索対象の文字列の長さを指定できる
console.log('abcde'.endsWith('bc',3)); // true

// 指定した文字列が含まれているかの判定
console.log('abcde'.includes('bc')); // true
console.log('abcde'.includes('ef')); // false
// 第2引数で検索の開始位置を指定できる
console.log('abcde'.includes('bc',3)); // false

文字列の分割(配列の取得)

const str = 'one,two,three,four,five';

// 指定した文字列で分割し配列で取得する
const words = str.split(',');
console.log(words); // ["one", "two", "three", "four", "five"]

// 第2引数で分割の上限を指定できる
const words2 = str.split(',', 3);
console.log(words2); // ["one", "two", "three"]

正規表現も使えます。

const str = 'one,two three;four:five';
const reg = /[\s,;:]/;
const words = str.split(reg);
console.log(words); // ["one", "two", "three", "four", "five"]

正規表現

matchで正規表現に一致した結果を取得できます。

const str = '2020-01-31';
const reg = /(\d+)-(\d+)-(\d+)/;
console.log(str.match(reg));
/*
0: "2020-01-31"
1: "2020"
2: "01"
3: "31"
index: 0
input: "2020-01-31"
groups: undefined
*/

?<名称>の形式でキャプチャした部分に名前を付けておくことができます。

const str = '2020-01-31';
const reg = /(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/;
const result = str.match(reg);
console.log(result);
/*
0: "2020-01-31"
1: "2020"
2: "01"
3: "31"
index: 0
input: "2020-01-31"
groups: Object
year: "2020"
month: "01"
day: "31"
*/
console.log(result.groups.month); // 01

正規表現のオプションでgを指定するとマッチした部分の全てを配列で取得できます。

const str = '2020-01-31';
const reg1 = /(\d+)/;
console.log(str.match(reg1));
/*
0: "2020"
1: "2020"
index: 0
input: "2020-01-31"
groups: undefined
*/

const reg2 = /(\d+)/g;
console.log(str.match(reg2));
/*
0: "2020"
1: "01"
2: "31"
*/

matchAllgオプションを指定した正規表現と組み合わせる事で、 マッチした結果の全てにアクセスできます。

const str = '2020-01-31';
const reg = /(\d+)/g;

for (const m of str.matchAll(reg)) {
  console.log(`${m[0]}, ${m.index}`);
  // "2020, 0"
  // "01, 5"
  // "31, 8"
}

const array1 = [...str.matchAll(reg)];
console.log(array1);
/*
0: "2020"
1: "2020"
index: 0
input: "2020-01-31"
groups: undefined
*/

const array2 = Array.from(str.matchAll(reg), m => m[0]);
console.log(array2); // ["2020", "01", "31"]

指定した正規表現とマッチした位置はsearchで取得できます。 位置が見つからない場合-1が返却されます。

const str = '1-23-456-7890';
console.log(str.search(/\d\d/g)); // 2
console.log(str.search(/\d\d\d\d\d/g)); // -1

置換はreplaceメソッドで文字列や正規表現を使って行う事ができます。

// 指定した文字列(の最初の1回)を置換する
console.log('abcABCabc'.replace('ab','xy')); // "xycABCabc"
// 指定した正規表現にマッチする部分を置換する
console.log('abcABCabc'.replace(/ab/ig,'xy')); // "xycxyCxyc"
// 置換後の文字列として、$1,$2,…で部分文字列を指定できる
console.log('2020-06-30'.replace(/(\d+)-(\d+)-(\d+)/,'$1/$2/$3')); // "2020/06/30"

関数を使って置換方法を指定することもできます。 以下はSI接頭辞の大きい方に変換するサンプルです。

function addMetricPrefix(n) {
  const number = Number(n);
  
  if(!Number.isFinite(number)){
    return String(n);
  }
  
  const log = Math.log10(number);
  
  const prefixMap = new Map([[3, 'k']
                           , [6, 'M']
                           , [9, 'G']
                           , [12, 'T']
                           , [15, 'P']
                           , [18, 'E']
                           , [21, 'Z']
                           , [24, 'Y']
                          ]);
  
  const key = [...prefixMap.keys()].sort((a, b) => b - a).find((x) => x <= log );
  
  if(!key){
    return String(n);
  }

  return String(number / (10 ** key)) + prefixMap.get(key);
}

let str = '123000000 * 10000 = 1230000000000';
let reg = /(\d+)/g;
console.log(str.replace(reg, addMetricPrefix)); // "123M * 10k = 1.23T"

文字列の取得や整形

// 文字列の連結
console.log('abc'.concat('XYZ','123')); // "abcXYZ123"

// Unicode 正規化形式の取得
console.log('\u00C5'); // "Å"
console.log('A\u030A'); // "Å"
console.log('\u00C5'.normalize()); // "Å"
console.log('A\u030A'.normalize()); // "Å"
console.log('\u00C5' === 'A\u030A'); // false
console.log('\u00C5'.normalize() === 'A\u030A'.normalize()); // true

// 指定した文字数になるまで文字列を増やす
console.log('123'.padStart(5, '0')); // "00123"
console.log('123'.padEnd(5, '0')); // "12300"

// 文字列の繰り返し
console.log('abc'.repeat(3)); // "abcabcabc"

// 指定したインデックス以降で文字列を切り出し
console.log('abcdefg'.substring(2)); // "cdefg"
// 指定したインデックスの範囲で文字列を切り出し
console.log('abcdefg'.substring(2,5)); // "cde"
// 指定したインデックスが文字列の長さより大きい場合は空文字
console.log('abcdefg'.substring(10)); // ""
// 開始位置が終了位置未満の場合、引数が交換される
console.log('abcdefg'.substring(5,2)); // "cde" substring(2,5)と同じ結果
// 引数がマイナスの場合、0として扱われれる
console.log('abcdefg'.substring(-1)); // "abcdefg"

// 指定したインデックス以降で文字列を切り出し
console.log('abcdefg'.slice(2)); // "cdefg"
// 指定したインデックスの範囲で文字列を切り出し
console.log('abcdefg'.slice(2,5)); // "cde"
// 指定したインデックスが文字列の長さより大きい場合は空文字
console.log('abcdefg'.slice(10)); // ""
// 開始位置が終了位置未満の場合は空文字
console.log('abcdefg'.slice(5,2)); // ""
// 引数がマイナスの場合、末尾からの文字数となる
console.log('abcdefg'.slice(-1)); // "g"
console.log('abcdefg'.slice(-5,-2)); // "cde"

console.log('abcXYZ'.toLowerCase()); // "abcxyz"
console.log('abcXYZ'.toLocaleLowerCase('en-US')); // "abcxyz"
console.log('abcXYZ'.toUpperCase()); // "ABCXYZ"
console.log('abcXYZ'.toLocaleUpperCase('en-US')); // "ABCXYZ"

// 空白文字の除去
console.log('  123abc   '.trim()); // "123abc"
console.log('  123abc   '.trimStart()); // "123abc   "
console.log('  123abc   '.trimEnd()); // "  123abc"

文字、文字コード取得

// 指定されたインデックスにある文字を取得
console.log('abcdefghi'.charAt(3)); // "d"
// 指定されたインデックスにある文字の文字コードを取得
console.log('abcdefghi'.charCodeAt(3)); // 100
// 指定されたインデックスにある文字の文字コードを取得
console.log('abcdefghi'.codePointAt(3)); // 100

Stringの静的メソッド

// 0から65535(0x0000~0xFFFF)の文字列
String.fromCharCode(0x2615,0x0061,0x2728,0x3042); // "☕a✨あ"
// コードポイントの文字列
String.fromCodePoint(0x2615,0x0061,0x2728,0x3042,0x1F9FF); // "☕a✨あ🧿"
// 文字リテラルの表現
String.raw`今年の年は${new Date().getFullYear()}年`; // "今年の年は2020年"
String.raw({raw  : ['','年','月','日'] }
  ,new Date().getFullYear(),new Date().getMonth()+1,new Date().getDate()); // "2020年6月18日"
作成日 : 2020年06月17日