可定制替換規則的文本替換器 – JAVA編程語言程序開發技術文章

可以根據需要改進:

1. 讓其不僅僅可以改SIM卡名稱,適用於普遍的替換。(考慮提取抽象類)

2. 使用Omission策略判斷可更多地使用正則表達式。(比如在判斷 “ sim ” 和 ”simple“上)
3. 有一些特殊例子符合Omission策略,而實際卻不能被忽略,這種情況應當能處理。(考慮修改Omission接口,增加一個會被優先處理的函數)

4. 改進效率,目前在太多的地方使用瞭String。

建議先閱讀 main(), 以便瞭解代碼功能。

package com.xxx.modify; 
 
import java.util.ArrayList; 
import java.util.List; 
 
/**
 * To change the sim name to uim name.
 * 
 * @author wycfgq@21cn.com
 * 
 */ 
public final class SimNameModifer { 
 
    // please make sure the length of 'SIM_STR' equals the length of 'UIM_STR' 
    private static final String[] SIM_STR = { "sim", "Sim", "SIM" }; 
    private static final String[] UIM_STR = { "uim", "Uim", "UIM" }; 
 
    /**
     * see main() in this class.
     */ 
    public static CharSequence change1(CharSequence c) { 
        return change2(c); 
    } 
 
    // TODO optimize: may use StringBuiler 
    /**
     * see main() in this class.
     */ 
    public static String change2(CharSequence c) { 
        if (c == null) 
            return null; 
 
        ArrayList<Omission> omits = new ArrayList<Omission>(); 
        omits.add(omitWord); 
 
        String str = c.toString(); 
        for (int i = 0; i < SIM_STR.length; i++) { 
            str = replace(str, SIM_STR[i], UIM_STR[i], omits); 
        } 
 
        return str; 
    } 
 
    // to omit the word include s1. 
    // (e. s1 = "sim", the "simple" will be omit) 
    private static Omission omitWord = new Omission() { 
        @Override 
        public boolean isOmit(String str, String s1, String s2, int from) { 
            int i = str.indexOf(s1, from); 
            if (i < 0) 
                return false; 
 
            int before = i – 1; // the index before the s1 
            int after = i + s1.length(); 
            boolean haveBefore = before >= 0; 
            boolean haveAfter = after < str.length(); 
            if (haveBefore && isLetter(str.charAt(before))) 
                return true; 
            if (haveAfter && isLetter(str.charAt(after))) 
                return true; 
 
            return false; 
        } 
 
        private boolean isLetter(Character c) { 
            return c.toString().matches("[a-zA-Z]"); 
        } 
    }; 
 
    // according to the 'omits' rule2, replace all s1 in str with s2. 
    private static String replace(String str, String s1, String s2, 
            List<Omission> omits) { 
        // TODO check args and throw 
        int i = -1; 
        StringBuilder sb = new StringBuilder(str); 
        NO_REPLACE: while ((i = sb.indexOf(s1, i + 1)) >= 0) { 
            if (omits != null) { 
                for (Omission o : omits) { 
                    if (o.isOmit(str, s1, s2, i)) { 
                        continue NO_REPLACE; 
                    } 
                } 
            } 
 
            sb.replace(i, i + s1.length(), s2); 
        } 
 
        return sb.toString(); 
    } 
 
    // all System.out.println(…equals(…)) are print "true" 
    public static void main(String[] args) { 
        String s1 = "uim card is Uim card is UIM card, not simple."; 
        String s2 = "sim card is Sim card is SIM card, not simple."; 
        String result = change2(s2); 
        System.out.println(result); 
        System.out.println(s1.equals(result)); 
 
        result = change2("dsim"); 
        System.out.println(result); 
        System.out.println("dsim".equals(result)); 
 
        result = change2("simple"); 
        System.out.println(result); 
        System.out.println("simple".equals(result)); 
 
        System.out.println("the uim card".equals(change1("the sim card"))); 
        System.out.println("uim".equals(change1("sim"))); 
 
        result = change2("sim卡"); 
        System.out.println(result); 
        System.out.println("uim卡".equals(result)); 
 
        CharSequence csq1 = "the uim card"; 
        CharSequence csq2 = "the sim card"; 
        CharSequence re = change1(csq2); 
        System.out.println(re); 
        System.out.println(csq1.equals(re)); 
 
        System.out.println(null == change1(null)); 
    } 
} www.aiwalls.com
 
interface Omission { 
    /**
     * @param str
     * @param s1
     * @param s2
     * @param from
     * @return false: if want the 'str' to replace the 's1'(after index 'from')
     *         with 's2'.
     */ 
    public boolean isOmit(String str, String s1, String s2, int from); 

摘自 abh200的專欄

發佈留言