在群聊天中偶然看到这一问题,用代码实现了一下。java
实现思路是用数组接收传入的成对符号,循环遍历数组,将数组内0,1每两个当作一对,每次循环+2,而后在while循环中每次从开始查找成对符号,若是找到开始如(和结束如),则取出并标记开始符号在整个字符串的位置,用于后序排序。实现思路有点复杂了,直接上代码了。数组
第一种实现app
package com;ui
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
*
* 截取成对符号内的字符串并用","隔开输出
* 可同时传入多个成对符号
* @author ss
*
*/
public class StrTrim{
public static void main(String[] args) {
String str="(asj)d[f]adf{dd}d[asd]f{cccc}a(sdf)fh[k]j(vv)df[a]as{dddd}df";
String [] arr={"(",")","[","]","{","}"};
System.out.println("输出的结果为:"+subStr(arr,str));
}
public static String subStr(String[] arr,String str){
//获取值放进list集合
StringBuffer sb=new StringBuffer();
//最终result
StringBuffer rsb=new StringBuffer();
//存储每次截取的符号对在字符串开始位置
List<Integer> numsList=new ArrayList<Integer>();
//存储每次截取的字符串
List<String> list=new ArrayList<String>();
//临时字符串
String temp="";
//在字符串开始 结束为止
int start =0,end=0;
//截取后剩余的
String remain="";
//保留原传进的值
String ostr=str;
for (int i = 0; i < arr.length; i+=2) {
remain=str;
int num=0;
while(remain.contains(arr[i]) && remain.contains(arr[i+1])){
start =remain.indexOf(arr[i]);
end=remain.indexOf(arr[i+1]);
if( start < end ){
sb.append(remain.substring(start+1, end)).append(",");
temp=remain.substring(start+1, end);
list.add(temp);
//总长度-剩余长度+start开始位置 为当前坐标值
num=str.length()-remain.length()+start;
//System.out.println(num + "---" + "str length--"+ str.length() + "--remain-" +remain.length()+"--start="+start);
remain=remain.substring(end+1,remain.length());
numsList.add(num);
}else{.net
//这个break好像只能跳出if循环,不能跳出while循环,下面看另外一个案例排序
//想跳出while内的循环得用 outer:while(true){ //逻辑 break outer;}
break;
}
}
}
//将截取的值和位置存进map集合
Map<String, String> map = new TreeMap<String, String>();
for (int j = 0; j < list.size(); j++) {
ostr=ostr.replace(list.get(j), "");
map.put(String.valueOf(numsList.get(j)), list.get(j));
}
//将位置集合排序 从小到大
Collections.sort(numsList);
//取出最终排序后的结果
for (int i = 0; i < numsList.size(); i++) {
//System.out.println("key="+numsList.get(i)+"----value="+map.get(String.valueOf(numsList.get(i))));
rsb.append(map.get(String.valueOf(numsList.get(i)))).append(",");
}
System.out.println("传入的字符串str="+str);
System.out.println("传入的成对符号为:arr="+Arrays.asList(arr).toString());
System.out.println("截取到的字符串集合为list="+list.toString());
return rsb.toString().substring(0,rsb.length()-1);
}rem
}
运行后输出的结果为:字符串
传入的字符串str=(asj)d[f]adf{dd}d[asd]f{cccc}a(sdf)fh[k]j(vv)df[a]as{dddd}df
传入的成对符号为:arr=[(, ), [, ], {, }]
截取到的字符串集合为list=[asj, sdf, vv, f, asd, k, a, dd, cccc, dddd]
输出的结果为:asj,f,dd,asd,cccc,sdf,k,vv,a,dddd
总结,虽然能实现了,但因为按传入的成对符号的前后顺序迭代,致使传入的数组顺序不一样,可能会输出结果不一样,如bb{ 【(a)】}cc这种状况传入的数组为() {} 【】 改变顺序或获得不一样的字符串结果。get
-------------------------------------------------------------------------------------------------------string
上面只是初级的代码实现
请看下面代码 第二种实现
主要用正则截取的,用到外循环,switch case 和正则里的一些方法,while迭代后进入两种状况像是开关的两条路,总之感受比第一种方法高大上了好多,不足的是对于字符串中存在的半个括号问题会报错。只要传入的字符串是规则的有开始结束成对符号的,截取都是没问题的。
public static String getS(String str,StringBuilder newStr){
if(str.length()<=0){
return newStr.toString().substring(1);
}
Pattern pattern = Pattern.compile("[\\{\\}\\[\\]()<>《》]");
Matcher matcher = pattern.matcher(str);
int i=0,begin=0,end=0;
outer:
while(matcher.find()) {
String group=matcher.group(0);
switch(i){
case 0:{
begin=str.indexOf(group);
i++;
continue;
}
case 1:{
end=str.indexOf(group);
newStr.append(","+str.substring(begin+1,end));
i++;
continue;
}
default:break outer;
}
}
return getS(str.substring(end+1),newStr);
}
最终总结:感受写代码少经验不足,都会用最基础的思想或逻辑去实现功能,好比能用if else不会用switch case,能用冒泡排序不会用collections.sort()方法,并且对外循环基本不了解。虽然第一种方法能实现但可看出其实现思路和方法仍是很复杂的,但代码的优雅性并不高,像是用砖盖起的一个结构复杂的房子,感受第二种代码简单,实现思路和代码质量比较高,至少用的的带花纹的瓷砖盖起的房子。由此也感受到本身的功底不足。
虽然再往深挖两种思路都有问题或不足,但更须要明白的是功能实现要以需求为准,若是再解析更复杂的字符串如alsk【as{sd[sdf]f}d】djf等,可能须要更复杂的实现。我的小白,能力有限。
在此抛砖引玉了,但愿有兴趣的大神们踊跃发表本身的意见,欢迎评论。