从嵌套字符串中读取值
Read the values from nested string
我正在读取一个包含以下数据的文件。
{1 2 3{4 5 6{7 8 9}10 11}12 13 14 ......}
输出应该是
1 2 3 12 13 14 4 5 6 10 11 7 8 9
.这样的内部结构会有很多
我们正在逐行读取文件。内部组可以在任何地方开始和结束(从第 1 行开始到第 5 行结束。所以我们需要检查文件中的所有行)。
我尝试对每个内部组使用 Array-List of List 但它不起作用,因为我们在内部循环完成后也有一些数据,这些数据应该出现在内部组之前。
用大括号计数并使用嵌套for循环可以工作,但会影响性能。如果有更好的方法,请告诉我。最终结果应该是上述顺序的一个列表。
这可以使用 Stack
来完成,如图所示
String str = "{1 2 3{4 5 6{7 8 9}10 11}12 13 14}";
StringBuilder res = new StringBuilder();
Stack<StringBuilder> temp = new Stack<>();
for(char c : str.toCharArray()){
switch(c){
case '{':
if(!temp.isEmpty())temp.peek().append(",");
temp.push(new StringBuilder());
break;
case '}':
if(!temp.isEmpty())temp.peek().append(",");
res.insert(0,temp.pop());
break;
case ' ':
temp.peek().append(",");
break;
default:
temp.peek().append(c);
}
}
System.out.println(res); //1,2,3,12,13,14,4,5,6,10,11,7,8,9,
每次遇到 {
时都会创建一个新的 StringBuilder
来读取数字。一旦找到 }
,我们弹出并输出结果。这可以使用 regex
进行优化,以一次读取范围字符而不是一次读取单个字符。
不确定这是否适用于您。我正在为我自己的项目玩 jsoup,一个 HTML 解析器,并提出了这个想法。首先用左 div 标记替换所有左括号,用右 div 标记替换所有右括号。然后从外部 div 开始附加 div 的 ownTexts。示例:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class JsoupTest {
public static void main(String[] args){
String html = "{1 2 3 {4 5 6 {7 8 9}10 11}12 13 14}";
html = html.replaceAll("\{", "<div>").replaceAll("\}", "</div>");
System.out.println(html);
Document doc = Jsoup.parse(html);
Elements es = doc.select("div");
StringBuilder sb = new StringBuilder();
for(Element e :es){
sb.append(e.ownText());
sb.append(" ");
}
System.out.println(sb.toString());
}
}
// 1 2 3 12 13 14 4 5 6 10 11 7 8 9
另一种方法是在每个 { 或 } 处拆分字符串,并将数组的第一个元素与最后一个元素、第二个元素与倒数第二个元素连接起来,依此类推。示例:
public static void main(String[] args){
String str = "{1 2 3{4 5 6{7 8 9}10 11}12 13 14}";
String [] splited = str.replaceFirst("\{", "").split("\{|\}");
System.out.println(Arrays.toString(splited));
StringBuilder sb = new StringBuilder();
for(int i = 0, j = splited.length-1;i<j;i++,j--){
sb.append(splited[i]).append(" ").append(splited[j]).append(" ");
}
sb.append(splited[splited.length/2 ]);
System.out.println(sb.toString());
}
我正在读取一个包含以下数据的文件。
{1 2 3{4 5 6{7 8 9}10 11}12 13 14 ......}
输出应该是
1 2 3 12 13 14 4 5 6 10 11 7 8 9
.这样的内部结构会有很多
我们正在逐行读取文件。内部组可以在任何地方开始和结束(从第 1 行开始到第 5 行结束。所以我们需要检查文件中的所有行)。
我尝试对每个内部组使用 Array-List of List 但它不起作用,因为我们在内部循环完成后也有一些数据,这些数据应该出现在内部组之前。
用大括号计数并使用嵌套for循环可以工作,但会影响性能。如果有更好的方法,请告诉我。最终结果应该是上述顺序的一个列表。
这可以使用 Stack
来完成,如图所示
String str = "{1 2 3{4 5 6{7 8 9}10 11}12 13 14}";
StringBuilder res = new StringBuilder();
Stack<StringBuilder> temp = new Stack<>();
for(char c : str.toCharArray()){
switch(c){
case '{':
if(!temp.isEmpty())temp.peek().append(",");
temp.push(new StringBuilder());
break;
case '}':
if(!temp.isEmpty())temp.peek().append(",");
res.insert(0,temp.pop());
break;
case ' ':
temp.peek().append(",");
break;
default:
temp.peek().append(c);
}
}
System.out.println(res); //1,2,3,12,13,14,4,5,6,10,11,7,8,9,
每次遇到 {
时都会创建一个新的 StringBuilder
来读取数字。一旦找到 }
,我们弹出并输出结果。这可以使用 regex
进行优化,以一次读取范围字符而不是一次读取单个字符。
不确定这是否适用于您。我正在为我自己的项目玩 jsoup,一个 HTML 解析器,并提出了这个想法。首先用左 div 标记替换所有左括号,用右 div 标记替换所有右括号。然后从外部 div 开始附加 div 的 ownTexts。示例:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class JsoupTest {
public static void main(String[] args){
String html = "{1 2 3 {4 5 6 {7 8 9}10 11}12 13 14}";
html = html.replaceAll("\{", "<div>").replaceAll("\}", "</div>");
System.out.println(html);
Document doc = Jsoup.parse(html);
Elements es = doc.select("div");
StringBuilder sb = new StringBuilder();
for(Element e :es){
sb.append(e.ownText());
sb.append(" ");
}
System.out.println(sb.toString());
}
}
// 1 2 3 12 13 14 4 5 6 10 11 7 8 9
另一种方法是在每个 { 或 } 处拆分字符串,并将数组的第一个元素与最后一个元素、第二个元素与倒数第二个元素连接起来,依此类推。示例:
public static void main(String[] args){
String str = "{1 2 3{4 5 6{7 8 9}10 11}12 13 14}";
String [] splited = str.replaceFirst("\{", "").split("\{|\}");
System.out.println(Arrays.toString(splited));
StringBuilder sb = new StringBuilder();
for(int i = 0, j = splited.length-1;i<j;i++,j--){
sb.append(splited[i]).append(" ").append(splited[j]).append(" ");
}
sb.append(splited[splited.length/2 ]);
System.out.println(sb.toString());
}