假设可以在各个字符串中使用的字符没有限制,并且字符串可能为空。
编辑:
似乎正确的方法是使用分隔符,并避免出现在任何单个字符串中已存在的分隔符的出现。以下是我对此的尝试,这似乎有效。错过了任何会破坏它的案例吗?:
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);
}
}
}
答案 0 :(得分:1)
使用Vector of Strings并将其转换为JSON对象并存储JSON对象。
答案 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("&", "&").replace("\u0000", "&null;");
}
/** Reverses the above escaping and returns the result. */
String unescape(String escaped) {
return source.replace("&null;", "\u0000").replace("&", "&");
}
许多其他变体都是可能的。 (重要的是,取消时的替换与用于转义的替换顺序相反。)请注意,您仍然可以使用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();