网上转账时,易发现大部分银行的网银系统都提供了类似这样的功能,即:当用户在输入转账金额数字时,下面会有个显示框用于同步显示该金额对应的大写形式,如输入:“6109.23”,则对应显示的金额大写为:“陆仟壹佰零玖元贰角叁分”。下面就贴上实现此转换功能的简单java代码,注意:该程序只支持到“万亿”级。
private static String[] bigLetter = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
"柒", "捌", "玖" };
private static String[] unit = { "元", "拾", "佰", "仟", "万", "拾", "佰", "仟",
"亿", "拾", "佰", "仟", "万" };
private static String[] small = { "分", "角" };
public static String getCnString(String s) {
if ("".equals(s)) {
return "";
}
s = roundString(s);
int index = s.indexOf(".");
String intOnly = s.substring(0, index);
String part1 = numFormat(1, intOnly); // 整数部分转换
String smallOnly = s.substring(index + 1);
String part2 = "";
if ("00".equals(smallOnly)) {
part2 = "整";
} else {
part2 = numFormat(2, smallOnly); // 小数部分转换
}
String newS = part1 + part2;
newS = cleanZero(newS);
return newS;
}
private static String roundString(String s) {
if ("".equals(s)) {
return "";
}
double d = Double.parseDouble(s);
d = (d * 100 + 0.5) / 100;
s = new java.text.DecimalFormat("##0.000").format(d);
int index = s.indexOf(".");
String intOnly = s.substring(0, index);
if (intOnly.length() > 13) {
System.out.println("输入数据过大,整数部分最多13位!");
return "";
}
String smallOnly = s.substring(index + 1);
if (smallOnly.length() > 2) {
String roundSmall = smallOnly.substring(0, 2);
s = intOnly + "." + roundSmall;
}
return s;
}
private static String numFormat(int flag, String s) {
int sLength = s.length();
String newS = "";
for (int i = 0; i < sLength; i++) {
if (flag == 1) {
// 将整数部分转换为中文大写(带单位)
newS = newS + bigLetter[s.charAt(i) - 48]
+ unit[sLength - i - 1];
} else if (flag == 2) {
// 转换小数部分(带单位)
newS = newS + bigLetter[s.charAt(i) - 48]
+ small[sLength - i - 1];
}
}
return newS;
}
/**
* 把已经转换好的中文金额大写形式加以改进, 清理这个字符串里面多余的零,让这个字符串变得更加可观
* 注:传入的这个数据应该是经过splitNum()方法进行处理,这个字符串应该已经是中文金额大写形式表示的
*
* @param s
* @return
*/
private static String cleanZero(String s) {
if ("".equals(s)) {
return "";
}
// 如果用户开始输入了很多0,去掉字符串前面多余的零,
// 使其看上去更符合习惯
while (s.charAt(0) == '零') {
// 将字符串的零和它对应的单位去掉
s = s.substring(2);
// 如果用户当初输入的时候只输入了0,则只返回一个零
if (s.length() == 0) {
return "零";
}
}
// 字符串中存在多个零在一起的时候只读出一个零,并省略多余的单位
// 由于本人对算法的研究太菜了,只能用4个正则表达式去转换了,各位大吓别介意哈
String regex1[] = { "零仟", "零佰", "零拾" };
String regex2[] = { "零亿", "零万", "零元", "零整" };
String regex3[] = { "亿", "万", "元", "元整" };
String regex4[] = { "零角", "零分" };
// 第一轮:把零仟,零佰,零拾等字符串替换成一个零
for (int i = 0; i < 3; i++) {
s = s.replaceAll(regex1[i], "零");
}
// 第二轮:把零亿,零万,零元等情况
// 亿,万,元这些单位有些情况是不能省的,需要保留下来
for (int i = 0; i < 4; i++) {
// 当第一轮转换过后有可能有很多个零叠在一起,要把很多个重复的零变成一个零
s = s.replaceAll("零零零", "零");
s = s.replaceAll("零零", "零");
s = s.replaceAll(regex2[i], regex3[i]);
}
// 第三轮:把零角,零分字符串省略
for (int i = 0; i < 2; i++) {
s = s.replaceAll(regex4[i], "");
}
s = s.replaceAll("亿万", "亿");
return s;
}
public static void main(String[] args) {
String s = CnUpperCaser.getCnString("10080.79");
System.out.println("============" + s);
}
}