简体   繁体   English

String.split()导致创建一个空字符串,如何防止这种情况?

[英]String.split() is causing an empty string to be created, how do I prevent this?

I have a string that is a concatenation of smaller strings of the form refNum orderNum , as in a string that contains a reference number and the amount of items on an order eg BRICK1 10 . 我有一个字符串,该字符串是refNum orderNum形式的较小字符串的串联,如包含参考号和订单上项目数量的字符串,例如BRICK1 10 The larger concatenated string is a number of these smaller string pieced together and using a pound sign to divide them eg #BRICK1 10#BRICK2 20#BRICK3 30 . 较大的串联字符串是将这些较小的字符串拼凑在一起并使用井号将它们分开的数量,例如#BRICK1 10#BRICK2 20#BRICK3 30

When I use String.split() I'd like the result to be an array that has divided the larger string into its smaller elements so BRICK1 10 , BRICK2 20 and BRICK3 30 , however when I actually try to split the string using "#" as a delimiter I get a fourth string at the start of the array that is empty. 当我使用String.split()时,我希望结果是一个数组,该数组将较大的字符串分为较小的元素, BRICK1 10BRICK2 20BRICK3 30 ,但是当我实际上尝试使用“#作为定界符,我在空数组的开头获得了第四个字符串。

I'm not sure why this is happening, how do I prevent it? 我不确定为什么会发生这种情况,如何预防呢?

My long string is produced using this method 我的长字符串是使用这种方法产生的

public String getAllOrders()
    {
        String orderDetails = "";

        for(BrickOrder o : orderList)
        {
            String order = "#" + o.getReferenceNumber() + " " + o.getNumberOfBricks();
            System.out.println("ORDER: " + order);
            orderDetails = orderDetails.concat(order);
        }

        return orderDetails;
    }

Whilst the split method is used within a test class, here. 虽然在测试类中使用了split方法,但此处。

@Test
    public void testFullOrderListReturnedCorrectly()
    {
        sys.createOrder(10);
        sys.createOrder(100);
        sys.createOrder(1000); //Create three orders

        String orderList = sys.getOrders(); //Return full order list
        System.out.println(orderList);

        String[] orders = orderList.split("#");
        System.out.println(orders.length);
    }

You get an empty string at the start of the array because the string you are splitting starts with you chosen delimiter ( # ). 您将在数组的开头得到一个空字符串,因为要拆分的字符串以您选择的定界符( # )开始。 You can prevent it by removing it from the beginning before splitting (using method String.substring(int) for example). 您可以通过在拆分之前从一开始将其删除(例如,使用String.substring(int)方法String.substring(int)来防止它。

Example solution: 解决方案示例:

String[] orders = orderList.substring(1).split("#");

That's what split does. 这就是split所做的。 It splits your string by using the delimiter and keeps the string, even if its empty, if it's not the last string.(trailing empty strings are excluded) You could use a regex instead and a Pattern match. 它使用定界符对字符串进行分割,并且即使不是空字符串(即使不是最后一个字符串),也保留字符串(即使为空)。(排除空字符串)可以使用正则表达式和模式匹配。 But in this case I'd recommend to just check your orderList before you split it and remove the # if it's the first character: 但在这种情况下,建议您在拆分orderList之前先检查一下它,如果它是第一个字符,则删除#

String[] orders;
if (orderList.charAt(0) == '#') {
    orders = orderList.substring(1).split("#");
} else {
    orders = orderList.split("#");
}

I believe the issue is because of the "#" that you are appending to the start of the order string. 我认为问题是由于您要在订单字符串的开头附加“#”。

The way split works is, it will break the order string at every "#", and the first "#" is encountered right at the beginning of the order string, and hence that is an empty. 拆分的工作方式是,它将在每个“#”处断开订单字符串,并在订单字符串的开头立即遇到第一个“#”,因此该字段为空。

Depending on your requirement, either you can avoid appending this "#" at the start, or you remove the "#" before spiting, or you ignore the element of the spitted array. 根据您的要求,您可以避免在开始时附加此“#”,或者在吐出之前删除“#”,或者忽略分散数组的元素。

Hope this clarifies. 希望这可以澄清。

Try this (Java 8+ is required): 试试这个(需要Java 8+):

import java.util.Arrays;
    ...
String s = "#BRICK1 10#BRICK2 20#BRICK3 30";
String[] tokens = Arrays.stream(s.split("#")).filter(t -> !t.isEmpty()).toArray(String[]::new);

how do I prevent it? 我该如何预防?

By placing delimiter between the parts you want to get with split. 通过在想要分割的部分之间放置定界符。

Imagine, you want to split a stick in two. 想象一下,您想将一根棍子分成两部分。

How do you do it? 你怎么做呢? Where would be the point of application of force? 施加武力在哪里?

Option one:  ---V---

Option two: V---V--- (looks familiar?)

The former gives you two sticks, obviously, and the latter would give you an empty piece of stick in the beginning. 很明显,前者会给你两根棍子,而后者一开始会给你一根空棍子。 It just doesn't exist in a real world, while an empty string happen to exist in Java. 它只是在现实世界中不存在,而Java中恰好存在一个空字符串。

Check String#split documentation, it says exactly that: 查看String#split文档,它说的很准确:

Splits this string around matches of the given regular expression. 围绕给定正则表达式的匹配项拆分此字符串。

Use regex to safely (ie if any exist) remove all leading # chars, then split: 使用正则表达式安全地(例如,如果存在的话)删除所有前导#字符,然后拆分:

String[] ordersPairs = orderList.replaceAll("^#*", "").split("#+");

By splitting on "#+" , empty orders are also ignored/discarded. 通过分割"#+" ,空订单也将被忽略/丢弃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM