在Java中分割和裁剪字符串数组

5
我有一个与字符串相关的小问题。 这个字符串看起来像这样:A/46\-54.67/48\-6.94/52\2.41/54\0.00/38\-0.18/34\0.06/32\-27.22(...) 它是一个UDP请求的回答。请求的格式如下:R/46/48(...) /32(...),意思是:给我#46,#48 ...的值。回答如上所示。
目标: 最终我只想从字符串中获取每个请求的特定值作为double类型。 我的首选是一个带有3(或2)个参数的类。第一个参数将是字符串本身,第二个将是字符串中的位置(如46之后的值)。如果需要,第三个参数将是值的结尾,如/。它返回一个包含这些值的数组。
问题: 该字符串不一致。返回的值可以具有不同的数字并且可以被签署或未签署。唯一一致的是:A/46\(值46的数字)/48\(数字)/52\(数字)/54\(数字)/38\_/34\_/32\_。正如您所看到的,该值在“\ /”之间。我得到了一个“解决方案”,它在特定位置裁剪了值。但是当数字改变时,它会失败。
解决方案: (是的,我是一个真正的Java新手)我的尝试给了我一个看起来像这样的数组:
A/46
-54.67/48
-6.94/52
2.41/54
0.00/38
-0.18/34
0.06/32
-27.22
现在我不知道如何获取值的最后一部分以将它们转换为double类型(数组)。
希望我已经生动地描述了我的问题。
感谢您的评论和建议。

你是怎么尝试解析它的?你应该使用StringTokenizer类在/上进行分割。然后对每个-标记进行一些验证,可以再次在\上进行分割。 - SidJ
5个回答

3

/开始拆分,你会得到一个类似于字符串数组的东西:

[ "A", "46\\-54.67", ... ]

忘掉第一个元素,然后对于每个其他元素,执行以下操作:
Double.parseDouble(theElement.subString(theElement.indexOf('\\')))

这将为您获取所需的 `double`,您需要做的就是将这些 `double` 放在您想要的位置。
另一个解决方案是使用此正则表达式循环遍历字符串:
(\d+)\\(-?\d+\.\d+)

正则表达式的第一组捕获整数,第二组捕获双精度浮点数。
final Pattern p = Pattern.compile("(\\d+)\\\\(-?\\d+\\.\\d+)");

final Matcher m = p.matcher(resultString);

while (m.find())
     // deal with m.group(1), m.group(2)

3
这个基于正则表达式的代码可能适合你使用:

这段基于正则表达式的代码可能适合你的需求:

String str = "A/46\\-54.67/48\\-6.94/52\\2.41/54\\0.00/38\\-0.18/34\0.06/32\\-27.22/38";
Pattern p = Pattern.compile("\\\\(-?\\d+\\.\\d+)/(\\d+)");
Matcher m = p.matcher(str);
while (m.find()) {
    System.out.printf("Before: %s, After: %s%n", m.group(1), m.group(2));
}

输出:

Before: -54.67, After: 48
Before: -6.94, After: 52
Before: 2.41, After: 54
Before: 0.00, After: 38
Before: -0.18, After: 34
Before: -27.22, After: 38

编辑:将这些匹配值放入ArrayList中:

String str = "A/46\\-54.67/48\\-6.94/52\\2.41/54\\0.00/38\\-0.18/34\0.06/32\\-27.22/38";
Pattern p = Pattern.compile("\\\\(-?\\d+\\.\\d+)/(\\d+)");
Matcher m = p.matcher(str);
List<Double> beforeList = new ArrayList<Double>();
List<Integer> afterList = new ArrayList<Integer>();
while (m.find()) {
    beforeList.add(Double.parseDouble(m.group(1)));
    afterList.add(Integer.parseInt(m.group(2)));
}
System.out.printf("Before: %s, After: %s%n", beforeList, afterList);

我会将编译后的模式声明为 static final,这样每次解析字符串时就不必重新编译它,但我认为这种方法比多次调用 String.split[] 更有效。然而,在我的理解中,这种解决方案是错误的-错误的代码与错误的值相匹配。将模式更改为类似 [A]?/(\\d+)\\\\([\\-]?\\d+\\.\\d+) 的内容可以使代码和值排列整齐。 - n0741337
@n0741337:没有解决方案并不是错误的,你可以自己尝试上面的代码。是的,我同意编译的模式可以被设置为静态常量以获得更好的性能。 - anubhava
我认为“46”组应该与“-54.67”组对齐,因为代码“46”的返回值在str中紧随其后。我已经比较了两者的输出。我认为应该有7个find(),而不是6个。 - n0741337
这与fge的解决方案非常相似。我尝试了一下,它运行得很好。但是我对这个解决方案的问题在于组。我试图将值写入数组中,但这并不容易。 所以我尝试了Ruchira的解决方案,这个解决方案给了我我需要的东西。 但我会仔细研究这个解决方案。 感谢所有人的超快速响应。 - Peter
我已经编辑了我的答案,为您提供了一些编码帮助,以填充匹配值的数组列表。 - anubhava

1
我没有使用集成开发环境输入这段文字,所以可能存在一些小错误:
//Split at /
String[] parts = udpResponse.split("/");

//for each part (apart from the initial A)
for (int i=1; i<parts.length; i++) {

   //the part is of the form aaa\bbb where aaa and bbb are numbers
   String[] keyValue = parts[i].split("\\");
   double key = Double.parseDouble(keyValue[0]); //number before \
   double value = Double.parseDouble(keyValue[1]); //number after \

   //do whatever you like with the numbers... 
}

使用 String.split() 就可以解决这个问题了。其他答案中的正则表达式过于复杂。 - Code-Apprentice

1

试试这个

   String test="A/46\\-54.67/48\\-6.94/52\\2.41/54\\0.00/38\\-0.18/34\\0.06/32\\-27.22";
   String[] arr=test.split("\\\\");
   double[] dub=new double[arr.length];
   int k=0;
   for (String i:arr){
        if(i.split("/").length!=1) {
        dub[k]=Double.parseDouble(i.split("/")[1].trim());
        k++;
        }
   }

这个方法基本可行,它返回了一个数组,但是不幸的是,它返回的是键而不是值。所以我把 \\ 和 / 调换了一下位置,然后它就正常工作了。 感谢您的帮助。 - Peter

0

我建议您使用String.split()。这是一个方便的函数,用于相对简单的字符串解析,例如您在此处的示例。首先,您需要在“/”上拆分UDP回复。看起来您忽略了结果数组中的第一个和最后一个String。对于其余的String,您可以使用for循环依次调用String.split(),在“\”字符上进行拆分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接