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

Java 将多个字符串组合成单个字符串的智能方法,以后可以将其分离为原始字符串?,java,string,Java,String,假设单个字符串中可以使用的字符没有限制,并且字符串可能为空 编辑: 这样做的正确方法似乎是使用分隔符,并避免已存在于任何单个字符串中的分隔符的出现。下面是我对此的尝试,这似乎有效。有没有漏掉任何可以打破它的箱子 public static void main(String args[]) { Vector<String> strings = new Vector<String>(); strings.add("abab;jmma"); 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);
    }
}
publicstaticvoidmain(字符串参数[])
{
向量字符串=新向量();
添加(“abab;jmma”);
字符串。添加(“defgh;,;”;
字符串。添加(“d;;efgh;,;”;
字符串。添加(“”);
字符串。添加(“”);
字符串。添加(“;”);
字符串。添加(“;,;”);
字符串=联合收割机(字符串);
字符串=单独的(字符串);
System.out.println();
}
静态字符串组合(向量字符串)
{
StringBuilder=新的StringBuilder();
for(字符串:字符串)
{
//不要在第一个字符串前加分隔符
如果(!builder.toString().equals(“”)
{
生成器。追加(“;”);
}
string=string.replaceAll(“;”,“;”);
builder.append(字符串);
}
返回builder.toString();
}
静态向量分离(字符串)
{
向量字符串=新向量();
分离(字符串,字符串,0);
返回字符串;
}
静态void separate(字符串、向量字符串、int currendex)
{
int-nextIndex=-1;
int checkIndex=currendex;
while(nextIndex==-1&&checkIndex

}

您可以构建一个在内部存储单个字符串的类,然后在调用toString时输出字符串的连接版本。取回原始字符串很简单,因为您已经将它们单独存储。

您可以使用库(拆分器类和连接器类)在两行代码中使用相同的组件

公共字符串组合(集合字符串){
返回Joiner.on(“yourUniqueSeparator”).join(字符串);
}
公共Iterable分离(字符串到分离){
返回Splitter.on(“您的唯一分隔符”).split(toSeparate);
}

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

String[] separate(String string)
{
    return string.split(SEPARATOR, -1);
}
如果您确实无法对字符串内容进行任何假设,那么正确执行此操作的唯一方法就是转义源字符串中出现的分隔符序列(可以是单个字符)。显然,如果转义分隔符序列,则需要在分割后取消转义结果。(逃生机制可能需要至少一个额外的逃生/卸载。)

编辑

下面是一个逃逸和逃避的示例(受XML启发)。它假定分隔符序列是
“\u0000”
(单个空字符)


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

获取字符串向量,将其转换为JSON对象并存储JSON对象


(和)

如果要使用分隔文本,请查看opencsv。api相当容易使用,它负责处理转义引号等。但是,它将null值视为空字符串,因此如果输入为{“a”,null,“c”},则可能会得到、、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();

您是否可以控制非分隔符字符串?解决此问题的一种常见方法是定义一个简单的分隔符字符串/字符,然后禁止任何组成字符串包含分隔符。@Hovercraft,用于序列化/反序列化由字符串组成的类,以便在数据结构中持久化,该数据结构允许每个映射使用单个字符串。@dlev,这是一种可能性。但如果可能的话,我不希望限制字符,而且也不太复杂。一种常见的解决方案是使用单个字符作为分隔符,并在其中一个sting中出现时对其进行转义(例如,在其前面加一个反斜杠)。当然,如果转义字符出现在字符串中,它也必须被转义。应该指定:我将它们连接起来以便持久化,然后稍后重新解析存储的字符串。当我重新解析时,我以前的对象将不可用。关于转义机制有什么建议吗?也许我应该做一些像使用“;”这样的事情作为分隔符,在连接之前,我替换“;”的任何实例用“;;”表示。然后我必须手动解析字符串,因为String.split不能被指示忽略“;”的出现。所以,在我的手动解析中,我会查找奇数出现的“;”,我把原来的帖子加上去就是想这样做的。有什么反馈吗?嗯,这比我的解决方案要简单得多。主要是
/** 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;", "&");
}
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();