Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

Java JSP/Servlet

Javaでカンマやクォーテーションをエスケープする方法

投稿日:2021年4月13日 更新日:

<目次>

(1) Javaでカンマやクォーテーションをエスケープする方法
 (1-1) 実現方法・構文
 (1-2) サンプルプログラム
 (1-3) 参考:カンマとダブルクォーテーション両方のエスケープが必要な理由

(1) Javaでカンマやクォーテーションをエスケープする方法

JavaのStringにおいてカンマやクォーテーションをエスケープする方法をご紹介します。

(やりたい事のイメージ)
 
例えば、次のようなStringをJavaでcsvファイルに出力するケースを考えます。
String str = “abc \” def , ghi”;

何もエスケープしないと、出力は次のようにdefとghiの間のカンマ「,」がセパレータとして動作してしまい、次のようになります。

(図101)

これをエスケープ処理をする事により、次のように1つのセルに収める方法をご紹介します。
(図102)

(1-1) 実現方法・構文

対応としては以下の2種類の記号をエスケープ処理します。

①カンマ「,」のエスケープ
②ダブルクォーテーション「”」のエスケープ

これを行う事で、ダブルクォーテーション「”」もカンマ「,」も区切り文字ではなく、「文字列の一部」として扱われるようになります。

①カンマ「,」のエスケープ

カンマはcsvに出力する際にセパレータとなりセルが分かれてしまうため、両端をダブルクォーテーション「”」(正確にはString内のため「\”」)で囲う事で、カンマを文字列として扱う事ができます。
 
(構文)
if(str.contains(",")) {str = "\""+str+"\"";}

②ダブルクォーテーション「”」のエスケープ

次にダブルクォーテーションをエスケープ処理します。
 
先ほどのカンマのエスケープ処理をすると、今度は途中のダブルクォーテーションが文字列の区切り目となってしまい、またしても途中でセルが分かれてしまうため、「”」は「”[文字列]”の文字列の一部ですよ」と教えるためのエスケープをします。
 
具体的には、「”」を二重にする(正確にはString内のため「\”」)ことでエスケープできます。
 
(構文)
if(str.contains("\"")) {str = str.replace("\"", "\"\"");}

目次にもどる

(1-2) サンプルプログラム

今回は簡単なサーブレットを用意し、サーブレットのURLを呼び出すとcsvファイルがダウンロードされるような仕組みにします。

この仕組み自体は今回のテーマから外れるので深くは触れませんが、興味ある方は下記も併せてご参照ください。

 
簡単にご紹介すると、サーブレットのURLを呼び出すとPrintWriterクラスに追加した内容がcsvとして出力されるものです。
 
(図121)

(サンプルプログラム)
 
今回のテーマであるカンマ「,」とダブルクォーテーション「”」のエスケープに関係するのは「▲」の部分です。それ以外はcsvを生成するための記述になります。
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/IT0992_EscapeComma")
public class IT0992_EscapeComma extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //# csv出力準備(エンコーディング方式、出力時ファイル名の指定)
        String filename = "sample.csv";
        response.setHeader("Content-Type", "text/csv; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\""+filename+"\"");
        PrintWriter out = response.getWriter();

        //# ▲csv出力文言の設定(今回のテーマに関連する記述)
        //# ①[\']クォーテーション:Stringの先頭にあると、csv上で表示されなくなってまう)
        //# ②[,]カンマ:String中にあると、csv上で別セルに分かれてしまう)
        //# テスト文字列:"abc [①クォーテーション] def [②カンマ] ghi"
        String str = "abc \" def , ghi";

        //# ▲エスケープ処理&改行除去
        //# ①[\']クォーテーションのエスケープ
        if(str.contains("\"")) {str = str.replace("\"", "\"\"");}
        //# ②[,]カンマのエスケープ
        if(str.contains(",")) {str = "\""+str+"\"";}

        out.append(str);
    }
}

(1-3) 参考:カンマとダブルクォーテーション両方のエスケープが必要な理由

この記事を読んで、カンマさえエスケープすればcsvでセルが分かれるのを防げるのでは?と思われた方もいるかも知れません(ダブルクォーテーションのエスケープの必要性が不明瞭)。

そう思われた方のために、下記4パターンの結果を参考として掲載いたします。

(表)

  ダブルクォーテーション
エスケープ
 カンマ
エスケープ
パターン① ×(なし) ×(なし)
パターン② ×(なし) ○(あり)
パターン③ ○(あり) ×(なし)
パターン④ ○(あり) ○(あり)

・パターン①

どちらもエスケープしていないので、カンマ「,」がセパレータとして作動し、ghiは別セルになりました。

(図131)

・パターン②

カンマのエスケープで両端をダブルクォーテーション「”」で囲ったため、元々あった「”」と相まって「abc」を1つの塊としてみなし、「def , ghi”」を2つ目の塊とみなし、連結して「abc def , ghi」となるが、やはりカンマ「,」がセパレータとして作動し、ghiのみ別セルになりました。

(図132)

・パターン③

ダブルクォーテーション「”」のエスケープをして「abc “” def , ghi」となるが、カンマのエスケープをしていないため、やはりセパレータとして作動し、ghiのみ別セルになりました。

(図133)

・パターン④

両方エスケープしているため、カンマ「,」はちゃんと文字列中の文字として扱われ、かつダブルクォーテーション「”」も文字列中の文字として扱われ、結果「abc “ def , ghi」という文字列が1つのセルに収まりました。

(図134)

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-Java, JSP/Servlet

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

オープンアドレス法のアルゴリズムについて図を使ってご紹介

<目次> (1) オープンアドレス法のアルゴリズムについて図を使ってご紹介  (1-1) オープンアドレス法とは?  (1-2) オープンアドレス法のアルゴリズム  (1-3) オープンアドレス法の利 …

Javaで正規表現の使い方をご紹介+サンプルプログラム付き

<目次> (1) Javaで正規表現の使い方をご紹介  (1-1) 正規表現とは?  (1-2) Javaでの正規表現の使い方  (1-3) サンプルプログラム (1) Javaで正規表現の使い方をご …

int型のオーバーフロー(桁あふれ)とは?実際の発生パターンと併せてご紹介

  <目次> (1) int型のオーバーフロー(桁あふれ)とは?実際の発生パターンと併せてご紹介  (1-1) int型のオーバーフローとは?  (1-2) int型のオーバーフローが発生す …

サーバサイドJava(JSP&サーブレット)のFORM認証を用いたログイン画面の開発

(0)目次&概説 (1) サーバー側JavaのFORM認証  (1-1) 認証の種類  (1-2) FORM認証の特徴  (1-3) FORM認証の実装概要 (2) FORM認証の実装手順  (2-1 …

Javaのスレッドとは?概念やサンプルプログラムのご紹介

  <目次> (1) Javaのスレッドとは?概念やサンプルプログラムのご紹介  (1-1) Javaのスレッドとは?  (1-2) 方法①:Threadクラス継承の構文  (1-3) 方法 …

  • English (United States)
  • 日本語
Top