NcrCodec

@ITで数値文字参照から文字への変換に関するスレが盛り上がってるのを見ながら、暇つぶしにコーディング。

 /*
    NcrCodec
    NCR⇔文字列の相互変換。
 */

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class NcrCodec{
    // インスタンス化禁止
    private NcrCodec() {}
    
    // NCRエンコードを行う(10進表記)
    public static String encode(String str) {
        return encode(str, 10);
    }
    
    // NCRエンコードを行う(基数指定)
    public static String encode(String str, int radix) {
        String NCRheader;
        String NCRfooter = ";";
        
        if(radix == 10){
            NCRheader = "&#";
        }else if(radix == 16){
            NCRheader = "&#x";
        }else{
            // 基数は10,16しか認めない。
            throw new IllegalArgumentException("Illegal radix.");
        }
        
        StringBuffer sb = new StringBuffer();
        
        for(int i = 0 ; i < str.length() ; i++){
            sb.append(NCRheader);
            sb.append(Integer.toString((int)str.charAt(i), radix));
            sb.append(NCRfooter);
        }
        
        return sb.toString();
    }
    
    // NCRデコードを行う(10進、16進)
    public static String decode(String str) {
        Pattern pattern = Pattern.compile("&#(\\d+);|&#x([\\da-fA-F]+);");
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        Character buf;
        
        while(matcher.find()){
            if(matcher.group(1) != null){
                buf = new Character*1(;
            }
            matcher.appendReplacement(sb, buf.toString());
        }
        
        matcher.appendTail(sb);
        
        return sb.toString();
    }
}

コメントいいかげんすぎ<自分
decode()の"buf="で始まってる部分、もっとすっきり出来るような気がしなくもない。

*1:char)Integer.parseInt(matcher.group(1))); }else{ buf = new Character)((char)Integer.parseInt(matcher.group(2), 16