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

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

関連記事

JSP/Servletでポップアップを表示する方法について

  <目次> (1) JSP/Servletでポップアップを表示する方法について  (1-1) 実現したい事  (1-2) 構文  (1-3) サンプルプログラム (1) JSP/Servl …

Javaのabstractとは?抽象クラスの概要やサンプルPGをご紹介

<目次> (1) Javaのabstractとは?抽象クラスの概要やサンプルPGをご紹介  (1-1) 抽象クラス(abstract)とは  (1-2) 抽象クラスの目的や用途  (1-3) 抽象クラ …

JavaのhashCode()で31を掛け算する理由について

<目次> (1) JavaのhashCode()で31を掛け算する理由について  (1-1) ハッシュの計算のソースコード  (1-2) ソースコードに登場する代表的な変数  (1-3) ソースコード …

Javaで日付を整形する方法について

<目次> (1) Javaで日付を整形する方法について  (1-1) 構文  (1-2) サンプルプログラム (1) Javaで日付を整形する方法について 日付を扱っていて、例えば「Thu Dec 1 …

JavaのArrrayListとLinkedListの違いについて

<目次> (1) JavaのArrrayListとLinkedListの違いについて  (1-1) 比較表(ArrayList vs LinkedList)  (1-2) まとめ  (1-3) 参考 …

  • English (United States)
  • 日本語
Top