博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符串替换 方法讨论
阅读量:5340 次
发布时间:2019-06-15

本文共 10953 字,大约阅读时间需要 36 分钟。

日前接到一个Case:需要将一个源字符串中的某些字符按指定的规则替换成新的字符

目前规则主要有两种:1、新字符串替换旧字符串;2、两个字符串互换

遇到的问题:用一般的string.replace()方法,有可能会出现第一步替换的新字符会在接下来的替换中被当作原有的旧字符,从而被再次替换。

EXP:源字符串“ABCD”, 规则1:A->C; 规则2:C->D; 正确结果:CBDD  错误结果:DBDD

 

解决方式一:罕见字符法

主要思路:使用罕见字符(exp:"@#$$#@")作为中间替换步骤

Step1:将需要替换的oldchar全部替换为“@#$oldchar$#@”

Step2:将“@#$oldchar$#@”再全部替换为newchar

具体代码:

1 /** 2      * 替换字符串 3      * @param sOldString 需要替换的源字符串 4      * @param listReplaceRule 替换规则 5      * @param sOldWord 要替换的字符串 6      * @param sNewWord 替换后的字符串 7      * @throws IOException 8       9     public static String replaceSring(String sOldString,ArrayList listReplaceRule) throws IOException {10         String sOldWord = "";11         String sNewWord = "";12         String sRule = "";13         //Step 1: 通过罕见字符串:"@#$$#@","&*%%*&"将sOldWord,sNewWord位置互换14         for (int i = 0; i < listReplaceRule.size(); i++) {15             sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword"));16             sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword"));17             sRule = uFunc.getString(((Map) listReplaceRule.get(i)).get("rule"));18             if ("2".equals(sRule) && sOldString.indexOf(sOldWord) >= 0 && sOldString.indexOf(sNewWord) >= 0) {19                 sOldString = sOldString.replace(sOldWord, "@#$$#@");20                 sOldString = sOldString.replace(sNewWord, "&*%%*&");21                 sOldString = sOldString.replace("@#$$#@", sNewWord);22                 sOldString = sOldString.replace("&*%%*&", sOldWord);23             }24         }25         //Step 2:将sOldWord 替换成罕见字符串:@#$(" + sOldWord+ ")$#@26         for (int i = 0; i < listReplaceRule.size(); i++) {27             sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword"));28             sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword"));29             sRule = uFunc.getString(((Map) listReplaceRule.get(i)).get("rule"));30             if ("1".equals(sRule)) {31                 sOldString = sOldString.replace(sOldWord, "@#$(" + sOldWord+ ")$#@");32             }33         }34         //Step 2:将罕见字符串:@#$(" + sOldWord+ ")$#@ 替换成 sNewWord35         for (int i = 0; i < listReplaceRule.size(); i++) {36             sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword"));37             sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword"));38             sRule = uFunc.getString(((Map) listReplaceRule.get(i)).get("rule"));39             if ("1".equals(sRule)) {40                 sOldString = sOldString.replace("@#$(" + sOldWord + ")$#@",sNewWord);41             }42         }43         return sOldString;44 45     }

解决方式二:字符位置替换法

主要思路:记录全部需要替换的字符在源字符串OldString中的Index在List:listIndex中,循环源OldString,如果存在于listIndex中,则将index位置上的oldchar替换为newchar;

不存在则取源OldString中index位置的值。PS: 字符互换相当于2次的字符替换

Step 1:将rule1和rule2分拆为2个ArrayList

1 //将规则1和规则2分拆为2个ArrayList 2         ArrayList listRule1= (ArrayList)listReplaceRule.clone(); 3         ArrayList listRule2= new ArrayList(); 4         ArrayList alRule1Word=new ArrayList(); 5         ArrayList alRule2Word=new ArrayList(); 6         for (int i = 0; i < listReplaceRule.size(); i++) { 7             String sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword")); 8             String sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword")); 9             String sRule = uFunc.getString(((Map) listReplaceRule.get(i)).get("rule"));10             if ("2".equals(sRule) && sOldString.indexOf(sOldWord) >= 0 && sOldString.indexOf(sNewWord) >= 0) {11                 listRule1.remove(listReplaceRule.get(i));12                 Map obj=new HashMap();13                 obj.put("oldword",sOldWord);14                 obj.put("newword",sNewWord);15                 obj.put("rule","1");16                 listRule2.add(0,obj);17                 Map obj1=new HashMap();18                 obj1.put("oldword",sNewWord);19                 obj1.put("newword",sOldWord);20                 obj1.put("rule","1");21                 listRule2.add(0,obj1);22                 23                 alRule2Word.add(sOldWord);24                 alRule2Word.add(sNewWord);25             }26         }

 

Step 2:检查二义性

1 for (Object object : listRule1) {2             String sOldWord = uFunc.getString(((Map)object).get("oldword"));3             alRule1Word.add(sOldWord);4         }5         Set setRule1Word = new HashSet(alRule1Word);6         Set setRule2Word = new HashSet(alRule2Word);7         if(alRule1Word.size()!=setRule1Word.size()|| alRule2Word.size()!=setRule2Word.size())8             return null;

 

Step 3:先处理规则2,将需要互换的字符进行互换位置

1 SortedMap mStringIndex2 = getIndexMap(sOldString, listRule2); //返回要替换字符的位置SortedMap 2         for(int i = 0; i < sOldString.length(); i++) 3         { 4             if(mStringIndex2.containsKey(i)){ 5                 sBuilder=sBuilder.append(uFunc.getString(mStringIndex2.get(i)));             6             } 7             else { 8                 sBuilder=sBuilder.append(sOldString.substring(i,i+1)); 9             }10         }

 

Step 4:处理规则2后的字符串sBuilder赋值给源字符串sOldString

1 sOldString=sBuilder.toString(); 2 sBuilder.delete(0, sBuilder.length());//清空sBuilder

 

Step 5:再处理规则1,把旧字符替换成新字符

1 SortedMap mStringIndex1 = getIndexMap(sOldString, listRule1); //返回要替换字符的位置SortedMap 2         for(int i = 0; i < sOldString.length(); i++) 3         { 4             if(mStringIndex1.containsKey(i)){ 5                 int start=Integer.parseInt(((Map)mStringIndex1.get(i)).get("start").toString()); 6                 int lenghth=Integer.parseInt(((Map)mStringIndex1.get(i)).get("length").toString()); 7                 String word=((Map)mStringIndex1.get(i)).get("word").toString(); 8                 sBuilder=sBuilder.append(word);         9                 i=i+lenghth-1;10             }11             else {12                 sBuilder=sBuilder.append(sOldString.substring(i,i+1));13             }14         }

 

Step 6: 返回结果字符串

1 return sBuilder.toString();

 

完整代码:

1 */  2     /**  3      * 替换字符串  4      * @param sOldString 需要替换的源字符串  5      * @param listReplaceRule 替换规则  6      * @param sOldWord 要替换的字符串  7      * @param sNewWord 替换后的字符串  8      * @throws IOException  9      */ 10     public static String replaceSring2(String sOldString,ArrayList listReplaceRule) throws IOException { 11          12         StringBuilder sBuilder=new StringBuilder(); 13         //Step 1:将规则1和规则2分拆为2个ArrayList 14         ArrayList listRule1= (ArrayList)listReplaceRule.clone(); 15         ArrayList listRule2= new ArrayList(); 16         ArrayList alRule1Word=new ArrayList(); 17         ArrayList alRule2Word=new ArrayList(); 18         for (int i = 0; i < listReplaceRule.size(); i++) { 19             String sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword")); 20             String sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword")); 21             String sRule = uFunc.getString(((Map) listReplaceRule.get(i)).get("rule")); 22             if ("2".equals(sRule) && sOldString.indexOf(sOldWord) >= 0 && sOldString.indexOf(sNewWord) >= 0) { 23                 listRule1.remove(listReplaceRule.get(i)); 24                 Map obj=new HashMap(); 25                 obj.put("oldword",sOldWord); 26                 obj.put("newword",sNewWord); 27                 obj.put("rule","1"); 28                 listRule2.add(0,obj); 29                 Map obj1=new HashMap(); 30                 obj1.put("oldword",sNewWord); 31                 obj1.put("newword",sOldWord); 32                 obj1.put("rule","1"); 33                 listRule2.add(0,obj1); 34                  35                 alRule2Word.add(sOldWord); 36                 alRule2Word.add(sNewWord); 37             } 38         } 39  40         //Step 2:检查二义性 41         for (Object object : listRule1) { 42             String sOldWord = uFunc.getString(((Map)object).get("oldword")); 43             alRule1Word.add(sOldWord); 44         } 45         Set setRule1Word = new HashSet(alRule1Word); 46         Set setRule2Word = new HashSet(alRule2Word); 47         if(alRule1Word.size()!=setRule1Word.size()|| alRule2Word.size()!=setRule2Word.size()) 48             return null; 49         //Step 3:先处理规则2,将需要互换的字符进行互换位置 50         SortedMap mStringIndex2 = getIndexMap(sOldString, listRule2); //返回要替换字符的位置SortedMap 51         for(int i = 0; i < sOldString.length(); i++) 52         { 53             if(mStringIndex2.containsKey(i)){ 54                 sBuilder=sBuilder.append(uFunc.getString(mStringIndex2.get(i)));             55             } 56             else { 57                 sBuilder=sBuilder.append(sOldString.substring(i,i+1)); 58             } 59         }     60         //Step 4:处理规则2后的字符串sBuilder赋值给源字符串sOldString 61         sOldString=sBuilder.toString();  62         sBuilder.delete(0, sBuilder.length());//清空sBuilder 63         //Step 5:再处理规则1,把旧字符替换成新字符 64         SortedMap mStringIndex1 = getIndexMap(sOldString, listRule1); //返回要替换字符的位置SortedMap 65         for(int i = 0; i < sOldString.length(); i++) 66         { 67             if(mStringIndex1.containsKey(i)){ 68                 int start=Integer.parseInt(((Map)mStringIndex1.get(i)).get("start").toString()); 69                 int lenghth=Integer.parseInt(((Map)mStringIndex1.get(i)).get("length").toString()); 70                 String word=((Map)mStringIndex1.get(i)).get("word").toString(); 71                 sBuilder=sBuilder.append(word);         72                 i=i+lenghth-1; 73             } 74             else { 75                 sBuilder=sBuilder.append(sOldString.substring(i,i+1)); 76             } 77         } 78         //返回结果字符串 79         return sBuilder.toString(); 80     } 81     private static SortedMap getIndexMap(String sOldString,ArrayList listReplaceRule) throws IOException 82     {  83         SortedMap tmpMap = new TreeMap(); 84         for (int i = 0; i < listReplaceRule.size(); i++) { 85             String sOldWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("oldword")); 86             String sNewWord = uFunc.getString(((Map) listReplaceRule.get(i)).get("newword")); 87             //String sRid = uFunc.getString(((Map) listReplaceRule.get(i)).get("rid")); 88             if(sOldString.indexOf(sOldWord)>=0){ 89                 for (int j = 0; j < sOldString.length(); j++) { 90                     int index = sOldString.indexOf(sOldWord, j); 91                     if (index < 0) { 92                         break; 93                     } 94                     Map map = new HashMap(); 95                     map.put("start", sOldString.indexOf(sOldWord)); 96                     map.put("length", sOldWord.length()); 97                     map.put("word", sNewWord); 98                     tmpMap.put(index, map); 99                     j = index;100                 }101             }102         }103         return tmpMap;104     }

转载于:https://www.cnblogs.com/hugh151721/archive/2012/05/18/2508197.html

你可能感兴趣的文章
浅析原生js模仿addclass和removeclass
查看>>
Python中的greenlet包实现并发编程的入门教程
查看>>
java中遍历属性字段及值(常见方法)
查看>>
YUI3自动加载树实现
查看>>
当心JavaScript奇葩的逗号表达式
查看>>
C语言学习总结(三) 复杂类型
查看>>
HNOI2018
查看>>
【理财】关于理财的网站
查看>>
Ubunt中文乱码
查看>>
《当幸福来敲门》读后
查看>>
【转】系统无法进入睡眠模式解决办法
查看>>
省市县,循环组装,整合大数组
查看>>
like tp
查看>>
DCDC(4.5V to 23V -3.3V)
查看>>
kettle导数到user_用于left join_20160928
查看>>
activity 保存数据
查看>>
typescript深copy和浅copy
查看>>
hbuilder调底层运用,多张图片上传
查看>>
较快的maven的settings.xml文件
查看>>
随手练——HDU 5015 矩阵快速幂
查看>>