【问题标题】:Copy a string splitted to another string将拆分的字符串复制到另一个字符串
【发布时间】:2014-04-22 22:15:16
【问题描述】:

在类的某个地方我声明了一个临时字符串变量

String name;

我将使用它来存储来自文本的数据。文本有许多具有这两种格式的字段

Type: text/html

name=foo

对于这种情况,我对类型name=foo

的字段特别感兴趣

所以,我之前使用split打破了文本行

String lines[] = text.split("\n"); 

再一次,我将使用split 来识别所提到类型的字段。在下面的代码中,while 循环在检测到 name=foo 字段时停止,并在控制台中打印该字段的值。

int i = 0;  // Counter for the while cycle

while (!(lines[i].split("=")[0].equals("name"))) {
    i++;                      

    if (lines[i].split("=")[0].equals("name")) // If the field is name...
    System.out.println(lines[i].split("=")[1]); // Prints the value of the field

    name = lines[i].split("=")[1]; // <-- My problem is here
}

当我想将字段的值复制到前面提到的 String 变量时,我的问题就开始了,这给了我一个 java.lang.ArrayIndexOutOfBoundsException

我需要该字符串稍后对其进行处理。 安全地将该字段的值复制到字符串变量的任何想法?

【问题讨论】:

  • 您确定您的所有行[] 都包含“xxxx=xxxxxx”类型的数据吗?
  • 你应该显示“name”的类类型。
  • @SaraSeppola 文本可能包含“XXX:XXX”和“XXX=XXX”两种类型的数据。
  • 那么,如果它有一个: 而不是=,则生成的数组没有1 索引......你会收到你显示的(正确的)错误.

标签: java string syntax


【解决方案1】:

在 if 中添加括号可以避免两个问题:

  • 如果一行包含 no = 整个字符串在 [0] 中并且访问 [1] 将导致上述异常
  • 无论条件如何,您都在更改(覆盖)变量名

为了取悦编译器,您可能还想将名称初始化为 null

int i = 0;  // Counter for the while cycle

while (!(lines[i].split("=")[0].equals("name"))) {
    i++;                      

    if (lines[i].split("=")[0].equals("name")){ // If the field is name...
        System.out.println(lines[i].split("=")[1]); // Prints the value of the field

        name = lines[i].split("=")[1]; // <-- My problem is here
    }
}

【讨论】:

  • 谁赞成这个?完全不正确,与问题无关。
  • @BrianRoach 虽然我同意,但您应该始终检查元素的数量(因为 "name".split("=") 否则会很麻烦)这是迈向解决方案的一步
  • 经过检查,大体上解决了这个问题。获取字符串时的一点观察是,我不仅有字符串,还有断线,所以为了删除它们,我使用了 name.replaceAll("[\n\r]", ""); 类型的解决方案。
  • 通过边界检查提交了我的own answer。虽然在这种特定情况下可能没有必要,但它通常可以省去头痛和修补程序 ;-)
【解决方案2】:

在您的代码中:

String name;
name = lines[i].split("=")[1];

这里的名字每次都会覆盖。

我认为您正在寻找这样的东西:

String names[];

String lines[] = text.split("\n");
names[] = new String[lines.length];

在你的while循环里面做这样的事情:

names[i] = lines[i].split("=")[1];

【讨论】:

  • 虽然如果 OP 想要保留循环之外的所有名称,这是一个很好的提示,但它不会回答问题/解决问题。问题出现在 cmets 中;它们有两种不同的格式。
  • 我完全同意。这只是一个建议,因为 name 的值总是会被​​覆盖,因此将值分配给 name 变量是没有意义的。
【解决方案3】:

关于您的代码有很多需要注意的地方:

  • 您可能在if-语句之后错过了{},因此每次运行while-loop 都会更新名称
  • 您访问[1] 而不检查split("=") 产生了多少元素
  • 您几乎在每一行都调用了split("=") 4 次。通过引入临时变量来节省 CPU 时间!
  • 您可以用for-loop 替换您的while-loop,该循环也可以在第一行找到name=value,并且如果name=value 不在任何行内(您不要'不检查i是否小于lines.length)

我将您的 cmets 留在了我的答案中;随意删除它们。

变体 a(使用索引):

for (int i = 0; i < lines.length; i++) {
    // Only split once and keep X=Y together in name=X=Y by specifying , 2
    final String[] split = lines[i].split("=", 2);

    if (split.length == 2 && split[0].equals("name")){ // If the field is name...
        System.out.println(split[1]); // Prints the value of the field

        name = split[1]; // <-- My problem is here
        break; // no need to look any further
    }
}

变体 b(使用“for-each”):

for (String line : lines) {
    // Only split once and keep X=Y together in name=X=Y by specifying , 2
    final String[] split = line.split("=", 2);

    if (split.length == 2 && split[0].equals("name")) { // If the field is name...
        System.out.println(split[1]); // Prints the value of the field

        name = split[1]; // <-- My problem is here
        break; // no need to look any further
    }
}

【讨论】:

    【解决方案4】:

    我想您的问题是当您到达最后一行或不包含“=”符号的行时。你正在检查

    !(lines[i].split("=")[0].equals("name"))
    

    但是你给 i 加 1,所以现在这个条件可能是假的

    if (lines[i].split("=")[0].equals("name"))
    

    你会在这里得到 java.lang.ArrayIndexOutOfBoundsException

    name = lines[i].split("=")[1];
    

    如果该行不包含“=”。

    试试

    if (lines[i].split("=")[0].equals("name")) { // If the field is name...
        System.out.println(lines[i].split("=")[1]); // Prints the value of the field
    
        name = lines[i].split("=")[1];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 2015-02-05
      • 2017-12-19
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多