J2ME (Java ME) 精簡了 J2SE 的標準庫,String 缺失 split()、replaceAll()、URLEncoder 等常用方法。本文提供一個生產級 StringUtil 工具類,涵蓋 URL 編碼、字符分割、子串替換、HTML 標簽過濾四大核心功能,代碼輕量、無第三方依賴,可直接拷貝用於 J2ME/舊版 Android/嵌入式 Java 專案。
URLEncode(String) | 特殊字符 %XX 編碼 | HttpConnection GET/POST 參數編碼 |
| split(String, char) | 按單字符分割返回 String[] | 解析 CSV、管道符分隔數據 |
| replaceAll(from, to, source) | 全量替換子串 | 模板渲染、敏感詞過濾 |
| StringFilter(String) | 移除 <tag> 標簽 | 清洗 HTML 片段提取純文本 |
package util;
import java.util.Vector;
public final class StringUtil {
// 私有構造函數,防止實例化
private StringUtil() {}
/**
* URL 編碼:空格→%20,+→%2b,'→%27,/→%2F,.→%2E,
* <→%3C,>→%3E,#→%23,%→%25,&→%26,
* {→%7B,}→%7D,\→%5C,^→%5E,~→%7E,
* [→%5B,]→%5D
*/
public static String URLEncode(String url) {
if (url == null) return "";
StringBuffer buf = new StringBuffer(url.length() * 2);
for (int i = 0; i < url.length(); i++) {
char c = url.charAt(i);
switch (c) {
case ' ': buf.append("%20"); break;
case '+': buf.append("%2B"); break;
case '\'': buf.append("%27"); break;
case '/': buf.append("%2F"); break;
case '.': buf.append("%2E"); break;
case '<': buf.append("%3C"); break;
case '>': buf.append("%3E"); break;
case '#': buf.append("%23"); break;
case '%': buf.append("%25"); break;
case '&': buf.append("%26"); break;
case '{': buf.append("%7B"); break;
case '}': buf.append("%7D"); break;
case '\\': buf.append("%5C"); break;
case '^': buf.append("%5E"); break;
case '~': buf.append("%7E"); break; // 原碼 %73 有誤,已修正
case '[': buf.append("%5B"); break;
case ']': buf.append("%5D"); break;
default: buf.append(c);
}
}
return buf.toString();
}
/**
* 按字符分割字符串(J2ME 無 String.split)
* @param s 待分割字符串
* @param chr 分隔符字符(int 兼容 char)
* @return 子串數組,不含分隔符
*/
public static String[] split(String s, int chr) {
if (s == null) return new String[0];
Vector v = new Vector();
int prev = 0, curr;
while ((curr = s.indexOf(chr, prev)) >= 0) {
v.addElement(s.substring(prev, curr));
prev = curr + 1;
}
v.addElement(s.substring(prev));
String[] arr = new String[v.size()];
v.copyInto(arr);
return arr;
}
/**
* 全量替換子串
* @param from 被替換子串
* @param to 替換目標
* @param source 源字符串
* @return 替換後字符串,任一參數為 null 返回 null
*/
public static String replaceAll(String from, String to, String source) {
if (source == null || from == null || to == null) return null;
StringBuffer bf = new StringBuffer();
int idx;
while ((idx = source.indexOf(from)) != -1) {
bf.append(source.substring(0, idx)).append(to);
source = source.substring(idx + from.length());
}
bf.append(source);
return bf.toString();
}
/**
* 簡易 HTML 標簽過濾:移除所有 <...> 內容
* 注意:不處理屬性中包含 > 的情況,不支援巢狀標簽語義解析
*/
public static String StringFilter(String str) {
if (str == null) return "";
String now = str;
int start = -1, end = -1;
for (int i = 0; i < now.length(); i++) {
char c = now.charAt(i);
if (c == '<') start = i; // \u003C
else if (c == '>') end = i; // \u003E
if (start != -1 && end != -1) {
String tag = now.substring(start, end + 1);
str = replaceAll(tag, "", str);
// 重置索引,因字符串已縮短
now = str;
i = start - 1;
start = end = -1;
}
}
return str;
}
}
~ → %73 錯誤,正確為 %7E,已修正。split 語義。from="" 會導致死循環,業務層需保證非空。now 指向新字符串,索引回退 i = start - 1,保證不漏掉緊鄰標簽。public class StringUtilTest extends junit.framework.TestCase {
public void testURLEncode() {
assertEquals("%20%2B%27", StringUtil.URLEncode(" +'"));
}
public void testSplit() {
assertEquals(new String[]{"a","b","c"}, StringUtil.split("a|b|c", '|'));
assertEquals(new String[]{"abc"}, StringUtil.split("abc", '|'));
}
public void testReplaceAll() {
assertEquals("bbbccc", StringUtil.replaceAll("aaa", "", "aaabbbcccaaa"));
}
public void testStringFilter() {
assertEquals("文本區域", StringUtil.StringFilter("文本區域"));
assertEquals("a b", StringUtil.StringFilter("ac d"));
}
}
TextUtils.split 等)java.net.URLEncoder、String.split、String.replace、Jsoup.clean,更健壯、標準。將此 StringUtil.java 放入專案 util 包,即可解決 J2ME 字符串處理的 90% 需求,無需引入任何第三方 JAR,極致輕量。