言語別テンプレートリテラル・文字列補間の書き方|Python・Ruby・Swiftは実行して検証

文字列の中に変数や式を埋め込む書き方を、言語ごとにまとめます。JavaScriptではテンプレートリテラル、Pythonではf-string、Rubyなどでは文字列補間と呼ばれますが、やろうとしていることは同じです。

この記事は検証した範囲を明示します。当環境で実際に実行して出力を確認できたのは Python・Ruby・Swift の3言語です。残りの言語は公式ドキュメントの仕様にもとづいて書き、実行はしていません。どちらなのかは各節の冒頭に書きます。確認日は2026年9月28日です。

言語 検証 バージョン
Python 実行して確認 Python 3.9.6
Ruby 実行して確認 ruby 2.6.10
Swift 実行して確認 Apple Swift 6.3.3
JavaScript / C# / Kotlin / Rust / Go / Java / PHP 公式仕様にもとづく(未実行) —

旧版にあった「ベンチマークテスト結果」の節は削除しました。出典も測定条件も示せない数値だったためです。代わりに、実行できた2言語で自分で測った数値を後半に載せています。

Python — f-string【実行して確認】

文字列の前に f を付けると、{} の中が式として評価されます。Python 3.6 で入りました。

name, age = '太郎', 25
print(f'こんにちは、{name}さん。{age}歳ですね。')
# こんにちは、太郎さん。25歳ですね。

print(f'{age * 2}')          # 50        式が書ける
print(f'{3.14159:.2f}')      # 3.14      小数点以下2桁
print(f'{1234567:,}')        # 1,234,567 3桁区切り
print(f'{255:#x}')           # 0xff      16進
print(f'{0.25:.1%}')         # 25.0%     パーセント
print(f'{name:>10}|')        #         太郎|   右寄せ10文字
print(f'{name:^10}|')        #     太郎    |   中央寄せ
print(f'{{中括弧そのもの}}')    # {中括弧そのもの}

デバッグ記法(3.8以降)

= を付けると変数名と値を一緒に出せます。print デバッグがかなり楽になります。

print(f'{name=} {age=}')
# name='太郎' age=25

日付の書式もそのまま書ける

import datetime
print(f'{datetime.date(2026, 9, 28):%Y年%m月%d日}')
# 2026年09月28日

【実測】3.12より前のバージョンで引っかかる制限

Python 3.9.6 で実行して確認した制限です。いずれも Python 3.12(PEP 701)で解除されました。古い環境を使っている場合は今も引っかかります。

d = {'k': 'v'}

print(f'{d["k"]}')   # OK  … 外が ' 、中が " なら通る
print(f"{d["k"]}")   # SyntaxError: f-string: unmatched '['
                     #   同じ種類のクォートは入れ子にできない(3.12で解禁)

print(f"{1 +
 2}")                # SyntaxError: EOL while scanning string literal
                     #   式の途中で改行できない(3.12で解禁)

対処は単純で、外側と内側でクォートの種類を変えるだけです。3.12以降は同じクォートでも通りますが、古い環境でも動かすコードなら分けておくのが安全です。

Ruby — 文字列補間【実行して確認】

#{} の中が評価されます。ダブルクォートでしか展開されません。ここがPythonと違う点です。

name, age = "太郎", 25
puts "こんにちは、#{name}さん。#{age}歳ですね。"
# こんにちは、太郎さん。25歳ですね。

puts "#{age * 2}"                    # 50
puts "#{'%.2f' % 3.14159}"           # 3.14
puts "#{format('%d円', 1234)}"        # 1234円
puts "#{name.upcase} #{[1,2,3].sum}" # 太郎 6

# シングルクォートでは展開されない
puts '#{name}'                       # #{name}

式の中に if を書ける

Rubyの補間は式を丸ごと入れられます。if も式なのでそのまま書けます。

puts "#{if age >= 20 then "成人" else "未成年" end}"
# 成人

ヒアドキュメントでも展開される

puts <<~HEREDOC
  ヒアドキュメント
    名前は #{name}
HEREDOC
# ヒアドキュメント
#   名前は 太郎

Swift — 文字列補間【実行して確認】

\( ) の中が評価されます。

let name = "太郎", age = 25
print("こんにちは、\(name)さん。\(age)歳ですね。")
// こんにちは、太郎さん。25歳ですね。

print("\(age * 2)")   // 50

【実測】書式指定には import Foundation が必要

これは実行して初めて分かった落とし穴です。String(format:) は標準ライブラリではなく Foundation にあります。

// import を忘れると
let x = String(format: "%.2f", 3.14)
// error: no exact matches in call to initializer

import Foundation                      // ← これが必要
print("\(String(format: "%.2f", 3.14159))")   // 3.14

オプショナルはそのまま埋め込まない

nil になりうる値をそのまま補間すると Optional("値") のように出ます。実行して確認した挙動です。

let opt: String? = nil
print("\(opt ?? "未設定")")              // 未設定       ← nil合体演算子
print("\(String(describing: opt))")     // nil          ← 明示的に文字列化

let opt2: String? = "値"
print("\(opt2 as Any)")                 // Optional("値") ← そのまま出てしまう

表示用の文字列を作るときは ?? で既定値を与えるのが基本です。

複数行リテラルでも展開される

print("""
複数行リテラル
  名前は \(name)
""")

その他の言語【公式仕様にもとづく・当環境では未実行】

以下は当環境に処理系がないため実行していません。各言語の公式ドキュメントに記載されている構文です。実際に書く前に手元で動かして確かめてください。

JavaScript — テンプレートリテラル

バッククォートで囲み ${ } で埋め込みます。ES2015で導入されました。そのまま複数行が書けるのが大きな利点です。

const name = "太郎", age = 25;
console.log(`こんにちは、${name}さん。${age}歳ですね。`);
console.log(`合計: ${1 + 2}`);

// 複数行がそのまま書ける
console.log(`1行目
2行目`);

タグ付きテンプレートリテラルという仕組みもあり、埋め込む値を関数で加工できます。HTMLエスケープやSQLの安全な組み立てに使われる形です。

function esc(strings, ...values) {
  return strings.reduce((acc, s, i) =>
    acc + s + (values[i] == null ? "" :
      String(values[i]).replace(/[&<>"']/g, c =>
        ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }))), "");
}
const input = '<script>alert(1)</script>';
console.log(esc`入力: ${input}`);

C# — 文字列補間

文字列の前に $ を付け { } で埋め込みます。C# 6 で導入。

var name = "太郎"; var age = 25;
Console.WriteLine($"こんにちは、{name}さん。{age}歳ですね。");
Console.WriteLine($"{3.14159:F2}");        // 書式指定
Console.WriteLine($"{(age >= 20 ? "成人" : "未成年")}");

Kotlin — 文字列テンプレート

$変数 で直接、式は ${ } で囲みます。

val name = "太郎"; val age = 25
println("こんにちは、${name}さん。${age}歳ですね。")
println("$name")            // 単純な変数は波括弧を省略できる
println("${name.length}")   // 式やプロパティは波括弧が必要

Rust — format! マクロ

Rustには文字列補間の構文はなく、マクロを使います。Rust 2021 以降は {name} のように変数名を直接書ける形も使えます。

let name = "太郎";
let age = 25;
let s = format!("こんにちは、{name}さん。{age}歳ですね。");
println!("{}", s);
println!("{:.2}", 3.14159);       // 書式指定
println!("{0}と{1}と{0}", "A", "B");  // 位置指定

Go — fmt.Sprintf

Goにも補間構文はありません。fmt.Sprintf を使います。

name, age := "太郎", 25
s := fmt.Sprintf("こんにちは、%sさん。%d歳ですね。", name, age)
fmt.Println(s)
fmt.Printf("%.2f\n", 3.14159)

Java — String.format とテキストブロック

Javaにも補間構文はありません。String.format を使います。複数行は Java 15 で入ったテキストブロック(""")が使えますが、テキストブロック自体に変数展開の機能はありません。

String name = "太郎";
int age = 25;
System.out.println(String.format("こんにちは、%sさん。%d歳ですね。", name, age));

// テキストブロック(Java 15+)。展開はされないので formatted() を併用する
String s = """
    名前: %s
    年齢: %d
    """.formatted(name, age);

PHP — ダブルクォート内の変数展開

$変数 がそのまま展開されます。配列やプロパティは {$...} で囲むのが安全です。

$name = "太郎"; $age = 25;
echo "こんにちは、{$name}さん。{$age}歳ですね。\n";
echo sprintf("%.2f\n", 3.14159);

// シングルクォートでは展開されない
echo 'こんにちは、$nameさん';   // こんにちは、$nameさん

言語別の書き方まとめ

言語 書き方 複数行 呼び名
JavaScript `${式}` できる テンプレートリテラル
Python f'{式}' ''' で囲む f-string
Ruby "#{式}" ヒアドキュメント 文字列補間
Swift "\(式)" """ で囲む 文字列補間
C# $"{式}" $"""(C# 11+) 文字列補間
Kotlin "$変数" / "${式}" """ で囲む 文字列テンプレート
PHP "{$変数}" Heredoc 変数展開
Rust format!("{name}") — (マクロ)
Go fmt.Sprintf("%s") — (書式指定)
Java String.format("%s") テキストブロック(展開なし) (書式指定)

大きく2つに分かれます。文字列の中に式を書ける言語(JS・Python・Ruby・Swift・C#・Kotlin・PHP)と、書式文字列と引数を分ける言語(Rust・Go・Java)です。後者は型チェックが効きやすいという利点があります。

性能|実行できた2言語で測った

「補間は遅いのか」を実際に測りました。結果はどちらの言語も補間が最速でした。

Python 3.9.6(各500万回)

書き方 合計 1回あたり
f"{n}は{a}歳" 0.486 秒 97 ns
"%sは%d歳" % (n, a) 0.553 秒 111 ns
"{}は{}歳".format(n, a) 0.719 秒 144 ns
n + "は" + str(a) + "歳" 0.774 秒 155 ns

ruby 2.6.10(各300万回)

書き方 合計 1回あたり
"#{n}は#{a}歳" 0.455 秒 152 ns
n + "は" + a.to_s + "歳" 0.546 秒 182 ns
format("%sは%d歳", n, a) 0.798 秒 266 ns

補間は読みやすさと速さを同時に取れます。「速度のために連結や format を使う」という選択には根拠がありません。ただしいずれも1回100〜300ナノ秒で、数万回程度なら合計は数ミリ秒です。普通のコードでは速度を理由に書き方を選ぶ必要はありません。読みやすさで決めてください。

【最重要】SQLとHTMLには使ってはいけない

この記事でいちばん伝えたい点です。補間は便利ですが、SQL文とHTMLの組み立てに使うと脆弱性になります。実際に動かして確認しました。

import sqlite3
con = sqlite3.connect(':memory:')
con.execute('CREATE TABLE users(name TEXT, admin INT)')
con.execute("INSERT INTO users VALUES ('太郎', 0)")

evil = "' OR 1=1 --"

# やってはいけない書き方
bad = f"SELECT * FROM users WHERE name = '{evil}'"
print(bad)
# SELECT * FROM users WHERE name = '' OR 1=1 --'
print(con.execute(bad).fetchall())
# [('太郎', 0)]   ← 条件が無効化され、全件返ってきた

# 正しい書き方(プレースホルダ)
print(con.execute('SELECT * FROM users WHERE name = ?', (evil,)).fetchall())
# []              ← 0件。文字列として正しく比較された

上の出力は実際の実行結果です。' OR 1=1 -- という入力で WHERE 句が無効化され、本来1件も返らないはずのクエリが全件を返しました。

対策はどの言語でも同じです。値を文字列に埋め込むのではなく、プレースホルダ(? や $1)でライブラリに渡します。ライブラリ側が型に応じたエスケープをします。

  • SQL|文字列を組み立てず、プレースホルダを使う
  • HTML|テンプレートエンジンの自動エスケープを使う。手で組むならエスケープ関数を必ず通す
  • シェルコマンド|文字列にせず、引数を配列で渡す
  • ログ|利用者の入力をそのまま補間すると、改行を混ぜて偽のログ行を作られる

「自分が書く値だから安全」という判断は危険です。今は固定値でも、後から変数に差し替えられます。SQLとHTMLでは最初からプレースホルダとエスケープを使う癖をつけてください。

使い分けの指針

  • 基本は補間を使う|読みやすく、測った範囲では最速
  • SQL・HTML・シェルには使わない|専用の安全な手段を使う
  • 同じ文を何度も組み立てるなら書式文字列を定数にする|翻訳(多言語化)が必要な場面では、文と値を分けておくほうが扱いやすい
  • 式を長く書きすぎない|補間の中に複雑な三項演算子を詰めると読めなくなる。手前で変数にする

まとめ

  • 呼び名は違うがやることは同じ。JSはテンプレートリテラル、Pythonはf-string、他は文字列補間
  • 式を埋め込める言語(JS・Python・Ruby・Swift・C#・Kotlin・PHP)と書式文字列を使う言語(Rust・Go・Java)に分かれる
  • Pythonの同じクォートの入れ子と式中の改行は3.12で解禁。それ以前では SyntaxError(実測)
  • Swiftの String(format:) は import Foundation が必要(実測)
  • Swiftでオプショナルをそのまま補間すると Optional("値") になる(実測)
  • 性能は補間が最速。Python 97ns、Ruby 152ns(実測)。普通のコードでは気にしなくてよい
  • SQLとHTMLには使わない。プレースホルダとエスケープを使う

文字列の組み立ては、どの言語でも最初に覚える部分です。テックジムでは東京・永田町の東京本校でゼロからはじめるPython入門講座(無料・対面・毎週開催)を開催しています。参加費はかかりません。

あわせて読みたい

掲載したコードのうちPython・Ruby・Swiftの出力とエラーメッセージ、および性能の数値は、2026年9月28日に当環境で実行して得たものです(Python 3.9.6 / ruby 2.6.10 / Apple Swift 6.3.3)。JavaScript・C#・Kotlin・Rust・Go・Java・PHP のコードは実行していません。各言語の公式ドキュメントにもとづく記述です。バージョンによって仕様が変わるため、使う前に手元で確認してください。

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら