「invalid non-printable character U+3000」エラーの原因と解決方法
- 作成日 2026.06.22
- その他
invalid non-printable character U+3000
syntax error: invalid non-printable character U+3000 in identifier
日本語環境で開発しているエンジニアが特に遭遇しやすいエラーです。見た目はただのスペースに見えるのにエラーになるという状況から、原因の特定に時間がかかりやすいのが特徴です。
本記事では以下の疑問に答えます。
- U+3000 とは何か・なぜ混入するのか
- どうやって見つけて削除するか
- Go・Python・JavaScript・SQL・シェルスクリプトでの対処法
- エディタの設定で予防する方法
- CI/CD で自動検出する方法
結論:先に答えを出す
# ① ファイルに U+3000(全角スペース)が含まれているか確認
grep -P "\x{3000}" ファイル名
grep -rn $'\xe3\x80\x80' . # UTF-8 バイト列で検索
# ② 行番号付きで確認
grep -Pn "\x{3000}" ファイル名
# ③ sed で全角スペースを半角スペースに置換
sed -i 's/\xe3\x80\x80/ /g' ファイル名
# ④ 全角スペースを削除(スペースに変換せず除去)
sed -i 's/\xe3\x80\x80//g' ファイル名
# ⑤ ディレクトリ全体を一括修正
grep -rl $'\xe3\x80\x80' . | xargs sed -i 's/\xe3\x80\x80/ /g'
U+3000 とは何か
文字の正体
U+3000 は IDEOGRAPHIC SPACE(表意文字スペース)、いわゆる全角スペースです。
U+0020 → 通常の半角スペース(ASCII)
U+3000 → 全角スペース(日本語・中国語・韓国語環境で使われる)
見た目はほぼ同じですが、コンピュータ上は全く異なる文字です。多くのプログラミング言語はソースコード内の全角スペースを**非表示文字(non-printable character)**として扱いエラーにします。
UTF-8 でのバイト表現
半角スペース U+0020 → 0x20 (1バイト)
全角スペース U+3000 → 0xE3 0x80 0x80 (3バイト)
よく混入する他の不可視文字
U+3000 以外にも問題になる不可視文字があります。
| コードポイント | 名称 | 主な発生源 |
|---|---|---|
U+3000 | IDEOGRAPHIC SPACE(全角スペース) | 日本語IME・日本語テキストのコピペ |
U+00A0 | NO-BREAK SPACE(ノーブレークスペース) | Web ページからのコピペ |
U+200B | ZERO WIDTH SPACE(ゼロ幅スペース) | Web ページ・Word からのコピペ |
U+200C | ZERO WIDTH NON-JOINER | アラビア語・ペルシャ語テキスト |
U+200D | ZERO WIDTH JOINER | 絵文字の結合文字 |
U+FEFF | BOM(バイトオーダーマーク) | Windows のテキストエディタ |
U+2028 | LINE SEPARATOR | Web ページ・JSON |
U+2060 | WORD JOINER | Office ドキュメント |
なぜ混入するのか
主な発生原因
1. 日本語 IME の誤入力
日本語入力モードのままスペースを押すと全角スペースが入力されます。特にコメントや文字列を日本語で書いた後、うっかりそのままコードを書くと混入します。
// コメントを日本語で書いた後、IMEをオフにせずスペースを押す
func main() { // ← func の後が全角スペース
2. 日本語テキストのコピー&ペースト
ドキュメント・メール・Slack・Web ページからコードをコピーすると、全角スペースがそのまま混入することがあります。
3. Word・Google Docs からのコピー
Office 系ツールは全角スペースや特殊スペースを多用します。
4. AI ツールの出力
ChatGPT・Claude などの AI が生成したコードをコピーする際、まれに全角スペースが混入することがあります。
5. Windows 環境で作成されたファイル
CRLF 改行や BOM(U+FEFF)が混入しやすい環境です。
検出方法
grep で検索
# 全角スペースを含む行を表示(UTF-8 バイト列で指定)
grep -n $'\xe3\x80\x80' ファイル名
# PCRE 正規表現で指定(-P オプション)
grep -Pn "\x{3000}" ファイル名
# ディレクトリ全体を再帰検索
grep -rn $'\xe3\x80\x80' .
grep -rPn "\x{3000}" .
# ファイル名だけ表示
grep -rl $'\xe3\x80\x80' .
# 複数の不可視文字をまとめて検索
grep -Pn "[\x{3000}\x{00A0}\x{200B}\x{FEFF}]" ファイル名
cat・od・hexdump で確認
# 制御文字・特殊文字を可視化
cat -A ファイル名
cat -v ファイル名
# 16進ダンプで確認(E3 80 80 が全角スペース)
od -c ファイル名 | grep -A1 "E3 80 80"
hexdump -C ファイル名 | grep "e3 80 80"
# xxd で確認
xxd ファイル名 | grep "e380 80"
Python で確認
# ファイルの中身を確認
with open("ファイル名", encoding="utf-8") as f:
for i, line in enumerate(f, 1):
if '\u3000' in line:
print(f"行 {i}: {repr(line)}")
# 全不可視文字を確認
import unicodedata
with open("ファイル名", encoding="utf-8") as f:
for i, line in enumerate(f, 1):
for j, char in enumerate(line):
if unicodedata.category(char) in ('Zs', 'Cc', 'Cf'):
if char not in (' ', '\n', '\r', '\t'):
print(f"行 {i} 文字 {j}: U+{ord(char):04X} ({unicodedata.name(char, '?')})")
Node.js で確認
const fs = require('fs');
const content = fs.readFileSync('ファイル名', 'utf8');
const lines = content.split('\n');
lines.forEach((line, i) => {
if (line.includes('\u3000')) {
console.log(`行 ${i + 1}: ${JSON.stringify(line)}`);
}
});
削除・修正方法
sed で置換・削除
# 全角スペースを半角スペースに置換
sed -i 's/\xe3\x80\x80/ /g' ファイル名
# 全角スペースを削除
sed -i 's/\xe3\x80\x80//g' ファイル Parameter名
# macOS の場合(GNU sed との違い)
sed -i '' 's/'"$(printf '\xe3\x80\x80')"'/ /g' ファイル名
# ディレクトリ全体を一括修正
grep -rl $'\xe3\x80\x80' . | xargs sed -i 's/\xe3\x80\x80/ /g'
# 特定の拡張子だけ修正
grep -rl $'\xe3\x80\x80' --include="*.go" . \
| xargs sed -i 's/\xe3\x80\x80/ /g'
Python で修正
import re
def fix_invisible_chars(filepath):
with open(filepath, encoding="utf-8") as f:
content = f.read()
# 全角スペースを半角スペースに
fixed = content.replace('\u3000', ' ')
# その他の不可視スペースも対応
fixed = fixed.replace('\u00a0', ' ') # NO-BREAK SPACE
fixed = fixed.replace('\u200b', '') # ZERO WIDTH SPACE(削除)
fixed = fixed.replace('\ufeff', '') # BOM(削除)
with open(filepath, "w", encoding="utf-8") as f:
f.write(fixed)
print(f"修正しました: {filepath}")
fix_invisible_chars("ファイル名.py")
# ディレクトリ全体を修正
import os
import glob
for filepath in glob.glob("**/*.py", recursive=True):
fix_invisible_chars(filepath)
tr コマンドで削除
# tr は Unicode の直接指定が難しいため cat + python で対応
cat ファイル名 | python3 -c "
import sys
content = sys.stdin.read()
print(content.replace('\u3000', ' '), end='')
" > 修正後ファイル名
VS Code で一括置換
Ctrl+H(Windows/Linux)または Cmd+H(macOS)で置換ダイアログを開く
検索欄に全角スペースを貼り付ける(または正規表現 \u3000 を使う)
置換欄に半角スペース(または空白)を入力
「ファイル内を置換」または「すべてのファイルで置換」をクリック
正規表現モードを有効にして \u3000 で検索することもできます。
言語別のエラーと対処法
Go
Go は全角スペースに最も厳しい言語のひとつです。
// ❌ エラーになるコード(全角スペースが混入)
func main() { // func の後が全角スペース
fmt.Println("Hello")
}
// syntax error: invalid non-printable character U+3000 in identifier
# Go ファイルの全角スペースを検出
grep -Pn "\x{3000}" *.go
# gofmt で整形(コード構造の問題は直らないが、スペースの確認はできる)
gofmt -e ファイル名.go
# 修正
sed -i 's/\xe3\x80\x80/ /g' ファイル名.go
Go ではビルド時・go vet 実行時にエラーが出るため、CI での早期検出が効果的です。
Python
# ❌ 全角スペースがインデントに混入
def hello(): # def の後が全角スペース
print("Hello") # インデントが全角スペース
# SyntaxError: invalid character ' ' (U+3000)
# または
# IndentationError: unexpected indent
# ✅ 検出スクリプト
import ast
import sys
def check_file(filepath):
with open(filepath, encoding="utf-8") as f:
source = f.read()
if '\u3000' in source:
lines = source.split('\n')
for i, line in enumerate(lines, 1):
if '\u3000' in line:
print(f"{filepath}:{i}: 全角スペースが含まれています")
print(f" {repr(line)}")
return True
return False
Python 3.12 以降はエラーメッセージが改善され、より分かりやすくなっています。
JavaScript / TypeScript
// ❌ 変数名や演算子の前後に全角スペース
const x = 1; // const の後が全角スペース
// SyntaxError: Invalid or unexpected token
// ❌ テンプレートリテラル内の全角スペースは文字列として残る(エラーにはならないが意図しない動作)
const msg = `Hello World`; // ← 全角スペースが文字列に含まれる
# ESLint で検出する設定
# .eslintrc.json
{
"rules": {
"no-irregular-whitespace": "error"
}
}
# ESLint を実行
npx eslint ファイル名.js
// TypeScript のコンパイラオプション
// tsconfig.json で strict モードを有効にすると一部検出できる
// ただし全角スペースの完全な検出は ESLint が確実
SQL
-- ❌ カラム名・テーブル名・キーワードに全角スペースが混入
SELECT * FROM users; -- キーワードの前後が全角スペース
-- ERROR: syntax error at or near " "
-- ❌ WHERE 句での混入
WHERE name = 'Alice';
# SQL ファイルの検出と修正
grep -Pn "\x{3000}" *.sql
sed -i 's/\xe3\x80\x80/ /g' *.sql
PostgreSQL・MySQL ともに SQL 文中の全角スペースはエラーになります。ただし文字列リテラルの中(' ' など)は文字として扱われます。
シェルスクリプト(bash / zsh)
# ❌ コマンドの前後に全角スペース
echo "Hello" # echo の後が全角スペース
# bash: echo : command not found
# ❌ 変数名に全角スペース
MY_VAR = "value"
# bash: MY_VAR : command not found
# ❌ if 文の条件
if [ "$x" = "1" ]; then
# 検出と修正
grep -Pn "\x{3000}" *.sh
sed -i 's/\xe3\x80\x80/ /g' *.sh
# shellcheck でシェルスクリプトを静的解析
sudo apt install shellcheck
shellcheck *.sh
YAML / JSON
# ❌ YAML のキーや値に全角スペース
name: Alice # コロンの後が全角スペース
age: 30
# yamllint で検出
yamllint ファイル名.yaml
// JSON の文字列値内の全角スペースはエラーにならないが意図しない動作の原因になる
{
"name": "Alice Bob" // ← 全角スペースが含まれている
}
# JSON の検出
python3 -c "
import json, sys
with open('ファイル名.json') as f:
content = f.read()
if '\u3000' in content:
print('全角スペースが含まれています')
for i, line in enumerate(content.split('\n'), 1):
if '\u3000' in line:
print(f' 行 {i}: {repr(line)}')
"
Dockerfile
# ❌ Dockerfile に全角スペースが混入
RUN apt-get update # RUN の後が全角スペース
# OCI runtime exec failed: ...
# Dockerfile の検出と修正
grep -Pn "\x{3000}" Dockerfile
sed -i 's/\xe3\x80\x80/ /g' Dockerfile
# hadolint で Dockerfile を静的解析
docker run --rm -i hadolint/hadolint < Dockerfile
エディタの設定で予防する
VS Code
// settings.json
{
// 全角スペースなどの不可視文字を可視化
"editor.renderWhitespace": "all",
// 問題のある文字をハイライト
"editor.unicodeHighlight.ambiguousCharacters": true,
"editor.unicodeHighlight.invisibleCharacters": true,
"editor.unicodeHighlight.nonBasicASCII": false,
// 日本語ファイルでも全角スペースを警告
"editor.unicodeHighlight.allowedLocales": {},
// 保存時に末尾スペースを削除
"files.trimTrailingWhitespace": true
}
VS Code では U+3000 などの問題文字にカーソルを当てると警告が表示されます。
Vim / Neovim
" 全角スペースを可視化(~/.vimrc)
highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=darkgray
match ZenkakuSpace / /
" autocmd で常に有効化
augroup ZenkakuSpace
autocmd!
autocmd ColorScheme * highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=darkgray
autocmd VimEnter,WinEnter,BufRead * let w:m1=matchadd('ZenkakuSpace', ' ')
augroup END
-- Neovim(init.lua)
vim.api.nvim_set_hl(0, 'ZenkakuSpace', { bg = '#3d3d3d', underline = true })
vim.fn.matchadd('ZenkakuSpace', ' ')
JetBrains IDE(IntelliJ・GoLand・PyCharm)
設定 → Editor → Code Style → General
→ "Other" タブ → "Show different font for non-ASCII characters" を有効化
または
設定 → Editor → Inspections → "Invisible characters" を有効化
Emacs
;; 全角スペースをハイライト
(require 'whitespace)
(setq whitespace-style '(face tabs tab-mark spaces space-mark))
(setq whitespace-space-regexp "\\(\u3000+\\)")
(global-whitespace-mode 1)
CI/CD で自動検出する
GitHub Actions
# .github/workflows/check-encoding.yml
name: Check for invalid characters
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for full-width spaces (U+3000)
run: |
# 全角スペースが含まれているファイルを検出
FILES=$(grep -rl $'\xe3\x80\x80' --include="*.go" \
--include="*.py" \
--include="*.js" \
--include="*.ts" \
--include="*.sh" \
--include="*.sql" \
. 2>/dev/null || true)
if [ -n "$FILES" ]; then
echo "❌ 全角スペース(U+3000)が含まれているファイルが見つかりました:"
echo "$FILES"
echo ""
echo "以下のコマンドで修正してください:"
echo " grep -rl \$'\\xe3\\x80\\x80' . | xargs sed -i 's/\\xe3\\x80\\x80/ /g'"
exit 1
fi
echo "✅ 全角スペースは見つかりませんでした"
- name: Check for other invisible characters
run: |
# BOM・ゼロ幅スペースなども検出
if grep -Prl "[\x{FEFF}\x{200B}\x{200C}\x{200D}]" \
--include="*.go" --include="*.py" --include="*.js" .; then
echo "❌ 不可視文字が含まれているファイルが見つかりました"
exit 1
fi
echo "✅ その他の不可視文字は見つかりませんでした"
pre-commit フック
# .git/hooks/pre-commit
#!/bin/bash
# コミット対象のファイルに全角スペースが含まれているか確認
FILES=$(git diff --cached --name-only --diff-filter=ACM)
FOUND=0
for FILE in $FILES; do
if [ -f "$FILE" ] && grep -Pq "\x{3000}" "$FILE"; then
echo "❌ 全角スペースが含まれています: $FILE"
grep -Pn "\x{3000}" "$FILE" | head -5
FOUND=1
fi
done
if [ "$FOUND" -eq 1 ]; then
echo ""
echo "コミットをブロックしました。以下のコマンドで修正してください:"
echo " grep -rl \$'\\xe3\\x80\\x80' . | xargs sed -i 's/\\xe3\\x80\\x80/ /g'"
exit 1
fi
chmod +x .git/hooks/pre-commit
pre-commit フレームワークを使う場合
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: local
hooks:
- id: no-fullwidth-space
name: No full-width space (U+3000)
language: pygrep
entry: "\u3000"
types: [text]
pip install pre-commit
pre-commit install
トラブルシューティング
grep で検索できない
# 環境によって正規表現の書き方が異なる
# GNU grep(Linux)
grep -Pn "\x{3000}" ファイル名
# macOS のデフォルト grep(BSD grep)は -P 非対応
# → Homebrew で GNU grep をインストール
brew install grep
ggrep -Pn "\x{3000}" ファイル名
# または perl で代替
perl -ne 'print "$.: $_" if /\x{3000}/' ファイル名
# または python で代替
python3 -c "
with open('ファイル名', encoding='utf-8') as f:
for i, line in enumerate(f, 1):
if '\u3000' in line:
print(f'{i}: {repr(line)}')
"
sed で置換できない(macOS)
# macOS の sed は GNU sed と挙動が異なる
# ❌ Linux では動くが macOS では動かない
sed -i 's/\xe3\x80\x80/ /g' ファイル名
# ✅ macOS 対応(-i の後に空文字列が必要)
sed -i '' 's/'"$(printf '\xe3\x80\x80')"'/ /g' ファイル名
# ✅ または Homebrew の GNU sed を使う
brew install gnu-sed
gsed -i 's/\xe3\x80\x80/ /g' ファイル名
# ✅ または Python で置換
python3 -c "
import sys
path = sys.argv[1]
with open(path, encoding='utf-8') as f:
content = f.read()
with open(path, 'w', encoding='utf-8') as f:
f.write(content.replace('\u3000', ' '))
print(f'修正完了: {path}')
" ファイル名
エラーが出る行が特定できない
# エラーメッセージに行番号がない場合
# ファイル全体を16進ダンプして確認
hexdump -C ファイル名 | grep -B2 -A2 "e3 80 80"
# Python で詳細な位置を表示
python3 -c "
with open('ファイル名', encoding='utf-8') as f:
for lineno, line in enumerate(f, 1):
for colno, char in enumerate(line, 1):
if char == '\u3000':
print(f'行 {lineno} 列 {colno}: U+3000 を検出')
"
修正後もエラーが出る
# 全角スペース以外の不可視文字が残っている可能性
python3 -c "
import unicodedata
with open('ファイル名', encoding='utf-8') as f:
for lineno, line in enumerate(f, 1):
for colno, char in enumerate(line, 1):
cat = unicodedata.category(char)
if cat in ('Zs', 'Cf') and char not in (' ', '\t'):
name = unicodedata.name(char, f'U+{ord(char):04X}')
print(f'行 {lineno} 列 {colno}: {name} (U+{ord(char):04X})')
"
# BOM が残っている場合
file ファイル名
# UTF-8 Unicode (with BOM) text ← BOM あり
# BOM を削除
sed -i '1s/^\xef\xbb\xbf//' ファイル名
よくある質問(FAQ)
Q1. 全角スペースとは何ですか?
日本語・中国語・韓国語(CJK)テキストで使われるスペースで、半角スペース(U+0020)の2倍の幅を持ちます。日本語 IME を使う環境では、スペースキーを押すと全角スペースが入力される設定になっていることがあります。
Q2. なぜ見た目で分からないのですか?
多くのエディタやフォントでは全角スペースと半角スペースをほぼ同じ見た目で表示します。特に等幅フォントでは区別がつきにくいです。VS Code の editor.unicodeHighlight 設定や Vim のハイライト設定で可視化することをおすすめします。
Q3. 全角スペースが入力されないようにするには?
IME の設定で、スペースキーを常に半角スペースにする設定があります。
Windows(Microsoft IME):
IME プロパティ → 詳細設定 → 「スペース入力」を「半角」に設定
macOS(日本語入力):
システム設定 → キーボード → 入力ソース
→ 「スペースバーの動作」を「スペース」に設定
Q4. 文字列の中の全角スペースはエラーになりますか?
言語によって異なります。
// Go:文字列リテラル内は OK
s := "Hello World" // ← エラーにならない(文字列の中)
fmt. Println(s) // ← エラー(コード中の全角スペース)
# Python:文字列内は OK、コード中はエラー
s = "Hello World" # ← OK(文字列の中)
x = 1 # ← SyntaxError(コード中)
Q5. U+3000 以外にも気をつけるべき文字はありますか?
よく問題になるのは以下です。
# まとめて検索
grep -Pn "[\x{3000}\x{00A0}\x{200B}\x{FEFF}\x{2028}\x{2060}]" ファイル名
特に Web ページやドキュメントからコピーした場合は U+00A0(ノーブレークスペース)や U+200B(ゼロ幅スペース)が混入しやすいです。
Q6. git diff で全角スペースを検出できますか?
# git diff でも確認できる
git diff | grep -P "\x{3000}"
# git log で特定コミットを確認
git show コミットハッシュ | grep -P "\x{3000}"
# git grep でリポジトリ全体を検索
git grep -Pn "\x{3000}"
まとめ
「invalid non-printable character U+3000」は全角スペースがソースコードに混入することで発生します。
検出:
grep -Pn "\x{3000}" ファイル名 # 単一ファイル
grep -rPn "\x{3000}" . # ディレクトリ全体
修正:
sed -i 's/\xe3\x80\x80/ /g' ファイル名 # 単一ファイル
grep -rl $'\xe3\x80\x80' . \
| xargs sed -i 's/\xe3\x80\x80/ /g' # 一括修正
予防:
- VS Code で
editor.unicodeHighlight.invisibleCharacters: trueを設定 - Vim で全角スペースをハイライト
- IME の設定でスペースを常に半角に
- pre-commit フックで自動検出
- CI/CD で
grep -rP "\x{3000}"を実行
日本語環境での開発では避けて通れない問題ですが、エディタの設定と CI での自動検出を組み合わせることで、混入を防ぐことができます。
参考リンク
文字コード関連
ツール
- pre-commit – Git フック管理ツール
- ESLint no-irregular-whitespace – ESLint ルール
関連記事(本サイト)
- Linux grep オプション一覧 – grepコマンドリファレンス
- Linux sed オプション一覧 – sedコマンドリファレンス
- Linux「command not found」エラーの解決方法 – よくあるLinuxエラー
- bash vs zsh 徹底比較 – シェルの選び方
本記事は2026年6月時点の情報をもとに、Ubuntu 24.04 LTS・macOS Sequoia・Go 1.22・Python 3.12 での動作確認に基づき作成しています。環境によってコマンドの挙動が異なる場合があるため、最新情報は各公式ドキュメントをご確認ください。
-
前の記事
【完全版】Linux OOM Killerの確認方法まとめ|ログの見方から原因調査・対策まで徹底解説 2026.06.22
-
次の記事
【完全版】Rails 8 アップグレードガイド|Rails 7からの移行手順・新機能 2026.06.22
コメントを書く