将以空格分隔的列表拆分

15

我经常需要完成这样一个任务:将由空格分隔的列表分成一个元素和包含尾部元素的数组。例如,给定以下字符串:

the quick brown fox
我们希望:
"the"
["quick","brown","fox"]

我希望在两个不同的变量中存储相同的值。第一个变量应该是一个字符串,第二个变量应该是一个数组。我正在寻找一种优雅的方法来实现这一点(最好是使用Java)。

8个回答

29

对于某些优雅值:

String input = "The quick brown fox";
String[] elements = input.split(" ");
String first = elements[0];
String[] trailing = Arrays.copyOfRange(elements,1,elements.length);

我想不出一种比现在更简洁的方法...


3
Arrays.copyOfRange() - 哇,谢谢!我每天都从别人的答案中学到新东西!(该方法是Java语言中用于复制数组中指定范围的元素的方法) - Carl Smotricz
1
如果用户打算从String[]数组中“弹出”一个项目,那么使用List会更好,对吧?(我想在他们让上述解决方案工作后,他们可能会意识到这一点)。 - Warren P

9
最优雅的方法可能是使用String.split获取String[],然后使用Arrays.asList将其转换为List<String>。如果您真的需要一个减去头部的单独列表,只需使用List.subList即可。
    String text = "the quick brown fox";
    List<String> tokens = Arrays.asList(text.split("\\s+"));

    String head = tokens.get(0);
    List<String> body = tokens.subList(1, tokens.size());

    System.out.println(head); // "the"
    System.out.println(body); // "[quick, brown, fox]"

    System.out.println(body.contains("fox")); // "true"
    System.out.println(body.contains("chicken")); // "false"

使用List可以利用Java集合框架提供的丰富功能。

另请参阅


1
尽管这比我的Arrays.copyOfRange()解决方案稍微多了一些代码,但我认为你的解决方案可能更加优雅,除非提问者需要极快的速度或处于非常低内存的环境中(在这种情况下,他/她为什么要使用Java呢?) - Alterscape

1

嗯,你可以通过这个得到大部分你想要的。

String[] pieces = "how now brown cow".split("\\s") 

大约如此。您的结果将是字符串数组。

如果您真的非常想要第一个项目与其余项目分开,那么您可以执行以下操作:

String head = pieces[0];
String[] tail = new String[pieces.length - 1];
System.arraycopy(pieces, 1, tail, 0, tail.length);

...完成。


1
你可以利用String#split()方法,并将限制作为第二个参数。
String text = "the quick brown fox";
String[] parts = text.split(" ", 2);
String headPart = parts[0];
String[] bodyParts = parts[1].split(" ");

System.out.println(headPart); // the
System.out.println(Arrays.toString(bodyParts)); // [quick, brown, fox]

1
package playground;

import junit.framework.TestCase;

public class TokenizerTest extends TestCase {

    public void testTokenize() throws Exception {
        String s = "the quick brown fox";
        MyThing t = new MyThing(s);
        assertEquals("the", t.head);
        String[] rest = {"quick", "brown", "fox"};
        assertEqualArrays(rest, t.rest);
    }

    private static void assertEqualArrays(String[] a, String[] b) {
        assertEquals(a.length, b.length);
        for (int i = 0; i < a.length; i++) 
            assertEquals(a[i], b[i]);
    }

    private static class MyThing {
        private final String head;
        private final String[] rest;

        public MyThing(String s) {
            String[] array = s.split(" ");
            head = array[0];
            rest = new String[array.length - 1];
            System.arraycopy(array, 1, rest, 0, array.length - 1);
        }

    }
}

1
public static void main(String[] args) {
        String s = "the quick brown fox";
        int indexOf = s.indexOf(' ');
        String head = s.substring(0, indexOf);
        String[] tail = s.substring(indexOf + 1).split(" +");
        System.out.println(head + " : " + Arrays.asList(tail));
    }

如果用Haskell的话会容易得多 :)


0
str= "the quick brown fox"
  pqr = str.split(" ")

0
使用 StringTokenizer 和 while 循环来遍历每个元素。在循环内部,您可以获取第一个元素并将其余部分放入数组中。
编辑:哦,我想 StringTokenizer 是一个“遗留”类(尽管它仍然有效)。
现在推荐的方法是使用 String.split()。这将给您一个包含您的元素的 String[]。从那里,获取第一个元素和创建剩余元素的数组应该很容易。

嗯。问题是,除非调用nextToken直到没有更多的令牌,否则您无法真正知道有多少令牌。所以您不能真正分配一个数组并将其放入其中? - Wram
没错,由于数组是不可变的,你必须使用System.arraycopy。但这是一个无意义的观点,因为最好使用其他人描述的split()方法。 - Jeff

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