将多个字符串组合成一个字符串的智能方法,以后可以将其分成原始字符串?

时间:2012-03-14 20:07:20

标签: java string

假设可以在各个字符串中使用的字符没有限制,并且字符串可能为空。

编辑:

似乎正确的方法是使用分隔符,并避免出现在任何单个字符串中已存在的分隔符的出现。以下是我对此的尝试,这似乎有效。错过了任何会破坏它的案例吗?:

public static void main(String args[])
{
    Vector<String> strings = new Vector<String>();
    strings.add("abab;jmma");
    strings.add("defgh;,;");
    strings.add("d;;efgh;,;");
    strings.add("");
    strings.add("");
    strings.add(";;");
    strings.add(";,;");


    String string = combine(strings);
    strings= separate(string);
    System.out.println();
}

static String combine(Vector<String> strings)
{
    StringBuilder builder = new StringBuilder();

    for(String string : strings)
    {
        //don't prepend a SEPARATOR to the first string
        if(!builder.toString().equals(""))
        {
            builder.append(";");
        }

        string = string.replaceAll(";", ",;");

        builder.append(string);
    }

    return builder.toString();
}

static Vector<String> separate(String string)
{
    Vector<String> strings = new Vector<String>();

    separate(string, strings, 0);

    return strings;
}

static void separate(String string, Vector<String> strings, int currIndex)
{
    int nextIndex = -1;
    int checkIndex = currIndex;

    while(nextIndex == -1 && checkIndex < string.length())
    {
        nextIndex = string.indexOf(';', checkIndex);
        //look back to determine if this occurance is escaped
        if(string.charAt(nextIndex - 1) == ',')
        {
            //this ones is escaped, doesn't count
            checkIndex = nextIndex + 1;
            nextIndex = -1;

        }
    }

    if(nextIndex == -1)
    {
        //no more remain  

        String toAdd = string.substring(currIndex, string.length());
        toAdd = toAdd.replaceAll(",;", ";");
        strings.add(toAdd);
        return;
    }
    else if(currIndex + 1 == nextIndex)
    {
        //empty string 

        strings.add("");
        separate(string, strings, nextIndex);
    }
    else
    {
        //there could be more

        String toAdd = string.substring(currIndex, nextIndex);
        toAdd = toAdd.replaceAll(",;", ";");
        strings.add(toAdd);
        separate(string, strings, nextIndex + 1);
    }
}

}

5 个答案:

答案 0 :(得分:1)

使用Vector of Strings并将其转换为JSON对象并存储JSON对象。

http://www.json.org/http://www.json.org/java/

答案 1 :(得分:0)

您可以构建一个在内部存储各个字符串的类,然后在调用toString时输出字符串的连接版本。获取原始字符串是微不足道的,因为您已经单独存储它们。

答案 2 :(得分:0)

使用Google Guava库(Splitter和Joiner类)可以在两行代码中使用相同的comportement。

public String combine(Collection<String> strings) {
    return Joiner.on("yourUniqueSeparator").join(strings);
}

public Iterable<String> separate(String toSeparate) {
    return Splitter.on("yourUniqueSeparator").split(toSeparate);
}

答案 3 :(得分:0)

使用您的代码,您可以使用split的双参数版本恢复空字符串:

String[] separate(String string)
{
    return string.split(SEPARATOR, -1);
}

如果你真的不能对字符串内容做任何假设,那么正确执行此操作的唯一方法是通过转义分隔符序列(可以是单个字符),无论它出现在源字符串中的哪个位置。显然,如果您转义分隔符序列,则需要在拆分后取消结果。 (逃逸机制可能需要额外的至少一个额外的逃逸/ unescape。)

修改

这是一个逃避和失败的示例(受XML启发)。它假定分隔符序列为"\u0000"(单个NULL字符)。

/** Returns a String guaranteed to have no NULL character. */
String escape(String source) {
    return source.replace("&", "&amp;").replace("\u0000", "&null;");
}

/** Reverses the above escaping and returns the result. */
String unescape(String escaped) {
    return source.replace("&null;", "\u0000").replace("&amp;", "&");
}

许多其他变体都是可能的。 (重要的是,取消时的替换与用于转义的替换顺序相反。)请注意,您仍然可以使用String.split()来分隔组件。

答案 4 :(得分:0)

如果要使用分隔文本,请查看opencsv。 api相当容易使用,它负责处理转义引号等。但是,它将空值视为空字符串,因此如果您的输入为{“a”,null,“c”},则可能会得到。如果这是不可接受的,您可以使用可识别的字符串并稍后将其转换回来。

char tokenSeparator = ',';
char quoteChar = '"';
String inputData[] = {"a","b","c"};

StringWriter stringWriter = new StringWriter();
CSVWriter csvWriter = new CSVWriter(stringWriter, tokenSeparator, quoteChar);
csvWriter.writeNext(inputData);
csvWriter.close();

StringReader stringReader = new StringReader(stringWriter.toString());
CSVReader csvReader = new CSVReader(stringReader, tokenSeparator, quoteChar);
String outputData[] = csvReader.readNext();