콘텐츠로 건너뛰기

🪢 문자열 이스케이프 / 언이스케이프

HTML 엔티티, JavaScript 문자열, JSON 문자열, Unicode(\uXXXX), URL 형식으로 문자열을 상호 변환합니다.

완전 무료 가입 불필요 브라우저 완결 5 개 언어 다크 모드

📖 변환 예

FormatRawEscaped
HTML<a>&lt;a&gt;
JSIt's 'ok'It\'s \'ok\'
JSONtab heretab\there
Unicode日本語\u65e5\u672c\u8a9e
URLa b&ca%20b%26c

🔗 관련 도구

📖 자주 걸리는 지점

HTML 엔티티·JavaScript 문자열·JSON·Unicode (\uXXXX)·URL·CSV·SQL·정규식·셸 등 14 가지 형식으로 문자열을 이스케이프 / 언이스케이프합니다. 처리는 브라우저 안에서 끝납니다. 다만 이스케이프는 「문자열을 변환하는 작업」이 아니라 「출력 대상의 문법에 맞추는 작업」입니다 — 이 도구는 당신의 출력 대상을 모르므로 어떤 형식을 골라야 하는지는 판정할 수 없습니다. 그리고 잘못된 형식을 적용하는 것은 아무것도 하지 않는 것보다 나쁜 결과가 됩니다. 안전해진 기분이 드는데 실제로는 지켜지지 않기 때문입니다.

사례 무슨 일이 일어나는가 어떻게 하면 되는가
문맥이 다르면 올바른 이스케이프도 다르다 같은 값이라도 놓이는 자리마다 필요한 처리가 다릅니다. <div> 안이라면 엔티티화로 충분하지만 href="..." 안에서는 URL 로서의 타당성도 요구되고, onclick="..." 안에서는 JavaScript 와 HTML 두 층을 동시에 만족시켜야 합니다. 나아가 HTML 이스케이프가 전혀 듣지 않는 문맥도 있습니다 — hrefjavascript: 로 시작하는 값이 들어가면 엔티티화해도 실행되고, <style> 안이나 <script> 안에서 &lt;그저 글자로 취급될 뿐 구문은 열린 채입니다. 「일단 HTML 이스케이프」가 통하지 않는 자리가 있다는 뜻입니다. 이스케이프는 출력하는 순간에, 템플릿 엔진에게 시키세요. Twig 의 |e('html_attr') / |e('js') / |e('url'), React 의 JSX, Go 의 html/template 처럼 문맥을 지정할 수 있는 구조를 쓰는 것이 정답입니다. 입력 시점에 이스케이프해서 저장하는 설계는 버리세요 — 저장한 값의 출력처가 하나라는 보장은 없고 메일 본문에도 CSV 에도 API 의 JSON 에도 흘러갑니다. 데이터베이스에는 늘 날 값을 넣고, 출력할 때마다 그 자리의 문맥으로 이스케이프한다. 이 원칙 하나로 위에 든 문제는 거의 전부 사라집니다. 이 도구는 그 결과가 맞는지 눈으로 확인하는 자리로 쓰세요.
이중 이스케이프 (&amp;lt; 가 화면에 나온다) 화면에 &lt;strong&gt;&amp; 가 그대로 보이는 상태입니다. 원인은 거의 언제나 「두 번 이스케이프했다」는 것이며, 전형은 저장할 때 애플리케이션이 이스케이프하고 표시할 때 템플릿 엔진이 다시 한 번 이스케이프하는 조합입니다. 무서운 점은 이것이 버그로 눈에 띄지 않는다는 것입니다 — 영숫자뿐인 데이터에서는 아무 일도 일어나지 않고 아포스트로피나 & 가 들어간 이름의 행만 깨집니다. 게다가 깨진 데이터는 이미 데이터베이스 안에 있으므로 표시 측을 고쳐도 낫지 않습니다. 반대 방향의 사고도 있습니다: JSON 의 \n 이 한 번 더 이스케이프되어 \\n 이 되고, 줄바꿈이어야 할 것이 화면에 두 글자로 나타나는 경우입니다. 먼저 어느 쪽에서 이중이 되고 있는지 가려내세요. 데이터베이스의 값을 그대로 여기에 붙여 넣고 「언이스케이프」 방향으로 HTML 을 고릅니다. 여기서 값이 변한다면 저장된 시점에 이미 이스케이프되어 있는 것 — 원인은 입력 측입니다. 변하지 않는다면 이중화는 표시 측에서 일어나고 있습니다. 복구는 한 번만 실행하는 마이그레이션으로 하고 반드시 대상을 좁히세요 (WHERE body LIKE '%&amp;%'). 전체 행에 무조건 html_entity_decode 를 걸면 원래 올바르게 &amp; 라고 쓰고 싶었던 행을 망칩니다. 실행 전에 반드시 백업을 뜨고 건수를 세어 본 뒤에 돌리세요.
이스케이프는 새니타이즈가 아니다 HTML 이스케이프는 「텍스트로서 안전하게 표시하는」 처리이지 사용자가 쓴 HTML 을 안전하게 그리는 처리가 아닙니다. 리치 텍스트 게시물처럼 태그를 허용하고 싶은 자리에서는 허용할 태그와 속성을 열거하는 새니타이저가 필요합니다. 같은 오해는 다른 형식에도 있습니다. SQL 문자열의 이스케이프 ('') 는 플레이스홀더의 대체가 되지 않습니다테이블명이나 컬럼명, ORDER BY 의 방향, LIKE 의 와일드카드 %_ 는 모두 문자열 이스케이프의 수비 범위 밖입니다. 셸의 따옴표도 마찬가지여서 값이 -rf 처럼 옵션으로 해석되는 상황은 따옴표로 막을 수 없습니다. 목적마다 쓰는 도구를 바꾸세요. 태그를 허용한다면 전용 새니타이저 (PHP 라면 HTML Purifier, JS 라면 DOMPurify) 를 쓰고 직접 만든 정규식으로 태그를 제거하려 하지 마세요 — 이 방향의 자작은 예외 없이 뚫립니다. SQL 은 항상 플레이스홀더를 쓰고 테이블명이나 정렬 순서처럼 바인딩할 수 없는 부분은 반드시 허용 목록과 대조하세요 (['name','created_at'] 에 포함된 값만 통과). 셸은 인자를 배열로 넘기는 API (execve 계열, Python 의 subprocess.run([...])) 를 쓰고 사용자 입력 앞에 -- 를 두어 옵션 해석을 끊습니다.

Unicode 이스케이프에는 BMP 바깥이라는 함정이 있습니다. \uXXXX 는 16 비트밖에 표현하지 못하므로 이모지나 일부 한자는 서로게이트 페어로 둘로 갈립니다 — 이모지 한 글자가 \ud83d\ude00 두 개가 된다는 뜻입니다. 여기서 글자 수를 세거나 도중에 자르면 글자가 반으로 갈려 깨집니다. ES6 이후라면 \u{1f600} 이라는 하나짜리 형식을 쓸 수 있습니다. 또 하나, 이 「비 ASCII 가 \uXXXX 로 둔갑하는」 성질은 검증을 방해합니다이 사이트 자신이 템플릿이 JS 용으로 이스케이프한 문자열을 일본어 그대로 grep 해서 「배포되지 않았다」고 두 번 오판했습니다. 올바른 순서는 검색하기 전에 \uXXXX 를 복호하는 것입니다. 마지막으로 하나만 지켜 주세요: 언이스케이프한 문자열을 JSON.parse 이외의 실행계에, 특히 eval 에 넘기지 마세요. 복호는 검사를 위한 조작이지 실행을 위한 조작이 아닙니다.

📖 사용법

  1. 1
    형식과 방향 선택
    변환 형식(HTML, JavaScript, JSON, Unicode, URL 등)과 방향(이스케이프/언이스케이프)을 선택하세요.
  2. 2
    텍스트 입력
    왼쪽 입력란에 텍스트를 붙여넣거나 입력하세요. 실시간으로 변환됩니다.
  3. 3
    결과 복사 또는 교체
    오른쪽 결과를 복사하거나 ⇄ 버튼으로 입출력을 바꿔 반대 방향으로 변환하세요.

❓ 자주 묻는 질문

HTML 이스케이프와 URL 인코딩의 차이는 무엇인가요?
HTML 이스케이프는 & < > "를 HTML 엔티티로 변환합니다. URL 인코딩은 특수 문자를 %20 같은 퍼센트 인코딩으로 변환합니다.
일본어 등 비 ASCII 문자도 이스케이프할 수 있나요?
네. Unicode(전체 문자) 또는 Hex(UTF-8 바이트) 모드를 선택하면 일본어 등 비 ASCII 문자도 모두 이스케이프할 수 있습니다.
SQL 인젝션 방지에 이 도구를 사용할 수 있나요?
SQL 모드로 작은따옴표를 이스케이프할 수 있지만, 프로덕션 환경에서는 반드시 준비된 명령문을 사용하세요.
🐛 이 도구에서 문제가 발생했나요?

무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.

※ 재현을 위해 브라우저 정보 (UA / 화면 / 언어 / URL) 가 자동 전송됩니다