JavaScript

JavaScriptのString.raw():バックスラッシュを保って文字列を作る

この記事でわかること

String.raw()でバックスラッシュを保った文字列を作る方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、埋め込み値の扱い、正規表現への応用と制約を学べます。

目的:バックスラッシュの重複を減らす

Windows形式のパスや正規表現をJavaScriptの文字列として書くと、バックスラッシュを重ねる必要があります。たとえば通常の文字列では、改行を表す\nと、バックスラッシュと英字の並びを表す\\nを書き分けます。

String.raw()は、テンプレートリテラルの固定部分に書いたバックスラッシュを保って文字列を作る関数です。読み手がエスケープの段数を数える負担を減らせます。ただし、すでに作られた文字列を元のソース表記へ戻す関数ではありません。

この記事では、固定部分と埋め込み値の違いを確認してから、桁数を指定する正規表現へ応用します。仕様の根拠はMDNのString.raw()リファレンスです。

動作環境と対応バージョン

確認日は2026年10月25日です。String.raw()はブラウザー専用APIではなく、JavaScriptの組み込み関数なので、ブラウザーとNode.jsの両方で利用できます。

MDNでは、主要ブラウザーで2015年9月から広く利用可能とされています。本記事は現在のChrome、Edge、Firefox、Safari、およびNode.js 22系・24系を対象にします。これらのNode.jsで追加パッケージや実験フラグは不要です。ここで示すNode.jsの版は記事の対象環境であり、最初に対応した版を示すものではありません。

古い実行環境も対象に含める場合は、typeof String.raw === "function"で関数の有無を確認できます。ただし、テンプレートリテラル自体を解釈できない環境では、機能判定に到達する前に構文エラーになります。

引数・戻り値と呼び出し方

普段はタグとして呼び出す

最もよく使うのは、String.rawの直後にバッククォートで囲んだテンプレートリテラルを書く形式です。この呼び出し方をタグ付きテンプレートと呼びます。

JavaScript
console.log(String.raw`folder\notes.txt`);

期待出力は次のとおりです。

CODE
folder\notes.txt

この場合、\nは改行ではなく、バックスラッシュとnの2文字として残ります。一方、${...}の式は評価され、その値が文字列へ組み込まれます。戻り値は文字列であり、配列やPromiseではありません。処理は同期的です。

通常の関数として呼ぶ場合

通常形式はString.raw(strings, ...substitutions)です。第1引数にはrawプロパティを持つオブジェクトを渡し、後続の引数には各区切りへ挿入する値を渡します。

JavaScript
console.log(String.raw({ raw: ["item=", "; count=", ""] }, "book", 3));

期待出力はitem=book; count=3です。タグとして呼ぶ場合、この引数の組み立てはJavaScriptエンジンが行います。通常のアプリケーションではタグ形式を選ぶと、固定部分と埋め込み値の対応を読み取りやすくなります。

実行方法と自己完結したコード

ブラウザーで実行する

任意の通常のWebページで開発者ツールのConsoleを開き、次のコード全体を貼り付けて実行します。外部通信やファイルアクセスはありません。再実行時に変数宣言が衝突しないよう、全体を関数で囲んでいます。

Node.jsで実行する

同じコードをUTF-8のraw-demo.cjsとして保存します。Node.jsをインストールした状態で、そのファイルを保存したフォルダーをターミナルで開き、次のコマンドを実行します。

Shell
node raw-demo.cjs

ファイルをnodeへ渡す手順はNode.js公式の実行例でも確認できます。以下のパス文字列は表示用のデータなので、Windows以外でも同じ内容を出力できます。

JavaScript
(() => {
  if (typeof String.raw !== "function") {
    console.log("この環境はString.rawに対応していません");
    return;
  }

  const fileName = "report.txt";
  const path = String.raw`C:\notes\${fileName}`;
  console.log(path);

  const normal = "A\nB";
  const raw = String.raw`A\nB`;
  console.log("normal length: " + normal.length);
  console.log("raw length: " + raw.length);
  console.log(raw);

  const inserted = "A\nB";
  const message = String.raw`value=${inserted}`;
  console.log("inserted newline: " + message.includes("\n"));

  function makeCodePattern(digits) {
    if (!Number.isInteger(digits) || digits < 1 || digits > 8) {
      throw new RangeError("digitsは1〜8の整数にしてください");
    }
    return new RegExp(String.raw`^ID-\d{${digits}}$`);
  }

  const pattern = makeCodePattern(3);
  console.log("ID-123: " + pattern.test("ID-123"));
  console.log("ID-12: " + pattern.test("ID-12"));

  try {
    makeCodePattern(0);
  } catch (error) {
    console.log(error.name + ": " + error.message);
  }
})();

期待出力を読み解く

仕様から導いた期待出力は次のとおりです。この記事の作成時にコードの実機実行は行っていません。

CODE
C:\notes\report.txt
normal length: 3
raw length: 4
A\nB
inserted newline: true
ID-123: true
ID-12: false
RangeError: digitsは1〜8の整数にしてください

通常の文字列normalでは改行が1文字になるため、長さは3です。rawではバックスラッシュとnが別々に残るため、長さは4になります。

insertedは通常の文字列として作った時点で改行を含んでいます。それを埋め込んでも、改行がバックスラッシュとnへ戻ることはありません。この違いが、固定部分と埋め込み値を区別するポイントです。

失敗例と制約

埋め込み値までエスケープされると思わない

String.raw()は、埋め込み値を安全な正規表現やHTMLへ変換しません。実例のdigitsを整数に限定したのは、正規表現の数量指定として使う値をアプリケーション側で管理するためです。

任意の検索語をそのまま正規表現へ埋め込むと、検索語に含まれる記号が正規表現の構文として解釈される場合があります。固定文字列を探すだけなら文字列検索を使うなど、目的に合う処理を先に選んでください。

また、パスを文字列にできても、存在確認やアクセス権の確認は行いません。ブラウザーからローカルファイルを自由に読めるようになる機能でもありません。

テンプレートの構文上の制約は残る

バッククォートは文字列の終端、${は埋め込みの開始として解釈されます。String.raw()を付けても、この構文はなくなりません。

特に、終端直前へバックスラッシュを1つだけ書くと、終端のバッククォートをエスケープしてしまいます。末尾にバックスラッシュを1つ置きたい場合は、埋め込み値として渡す方法があります。

JavaScript
(() => {
  const trailingSlash = "\\";
  const directory = String.raw`C:\notes${trailingSlash}`;
  console.log(directory);
})();

期待出力は次のとおりです。

CODE
C:\notes\

複数行で書けば実際の改行も文字列へ入ります。見た目を整えるために追加した行頭の空白も残るため、生成する文字列に不要な空白がないか確認してください。構文の詳細はMDNのテンプレートリテラル解説が参考になります。

引数の形を誤ると例外になる

通常の関数として単なる文字列を渡すのは誤りです。必要なrawプロパティがないため、次のコードはTypeErrorを捕捉します。

JavaScript
try {
  String.raw("plain text");
} catch (error) {
  console.log(error.name);
}

期待出力はTypeErrorです。各例の例外は同期的に発生するので、try...catchで処理できます。awaitは必要ありません。

活用事例と導入時の改善案

String.raw()は、ソース内へWindows形式のパス例、バックスラッシュを含む説明文、動的な正規表現を書く場面で役立ちます。実例のように固定の正規表現構文と数値の埋め込みを組み合わせると、二重のエスケープを減らしながら構造を読み取れます。

導入時は、バックスラッシュの多い箇所から置き換える方法を勧めます。通常のテンプレートリテラルを一括で変更すると、もともと改行やタブとして使っていた表記の意味まで変わるためです。

確認する際は表示だけでなく、長さや改行の有無も調べてください。本記事のようにlengthやincludes("\n")を併用すると、Consoleの表示形式に惑わされず、生成した文字列の違いを判断できます。

公式参考資料

PREFERRED SOURCES

Googleの優先するニュース提供元にSEの部屋を追加

Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。

Googleの設定画面で確認する 新しいタブで開きます

候補にSEの部屋が表示されない場合は、まだ追加できません。

y.
WRITTEN BY

y_ymo10

SEの部屋で、HTML・CSSからJavaScript・React・Next.jsまで、Web制作の開発ノートを公開しています。

ほかの開発ノートを読む →