假设我有两个随机生成的字符串。
如何生成一个包含两个字符串的字符串,同时能够将它们拆分成原始的两个字符串供以后使用?
例如,我有“[aweiroj \ 3aoierjvg0_3409”和“4093 w_ / e9”。如何将这两个单词附加到一个变量中,同时能够将它们拆分为原始的两个字符串?
我的问题是,我似乎找不到.spit()的正则表达式,因为这两个字符串可以有任何字符(alpabet,整数,\,/,空格......)。
我只想到了一个可以使用它的真实案例。 Sometimes,通过网络(HTTP)发送纯文本比xml或json更好。宽带速度慢的服务器 - 使用xml或json,宽带慢速的快速服务器 - 使用纯文本。以下答案可能会阻止纯文本注入。但是,这些方法没有进行基准测试或测试,我可能会在实际使用它们之前测试这些方法。
答案 0 :(得分:9)
简短的回答是:不要这样做。使用数组或具有两个数据成员的类,但将字符串组合成一个字符串可能是一个坏主意。
但如果你有一些真正模糊的用例,你可以:
创建一个足够独特的分隔符,例如"<<Jee Seok Yoon's Delimiter>>"
。
final static String DELIM = "<<Jee Seok Yoon's Unique Delimiter>>";
String a = /*...*/;
String b = /*...*/;
String combined = a + DELIM + b;
int breakAt = combined.indexOf(DELIM);
String a1 = combined.substring(0, breakAt);
String b1 = combined.substring(breakAt + DELIM.length());
如果字符串中存在,您可以使用更简单的分隔符。
记住第一个字符串的长度并将其存储在统一字符串中,后跟“end of length”分隔符。
String a = /*...*/;
String b = /*...*/;
String combined = String.valueOf(a.length()) + "|" + a + b;
int breakAt = combined.indexOf("|");
int len = Integer.parseInt(combined.substring(0, breakAt), 10);
String a1 = combined.substring(breakAt + 1, len);
String b1 = combined.substring(breakAt + 1 + len);
(两个代码示例都完全袖手旁观,未经测试。)
答案 1 :(得分:4)
我会创建一个包含两个字符串的类,并且能够将它们分开打印并组合在一起。
这个只是扩展了ArrayList,因此您无需重新实现add
,get
等等:
public class ConcatedString extends ArrayList<String>
{
public String concated() {
StringBuilder b = new StringBuilder();
for (String string : this)
{
b.append(string);
}
return b.toString();
}
}
答案 2 :(得分:3)
如果这是一些(模糊)类型的序列化问题,那么至少有一种明显的方法可以做到这一点。
使用某种编码对字符串进行编码(HTML编码是一种简单易读的选择)。选择编码字符串不可能包含的字符,将其用作分隔符并将它们连接起来。
然后,要检索,按字符分隔字符串并使用初始方法反向解码子字符串。
答案 3 :(得分:2)
如果您希望它在每种情况下都有效,则需要定义2个特殊字符:
1-Encoding:当您连接2个字符串时:
在两个字符串中,
然后将两个String与它们之间的分隔符字符连接起来。
2-Decoding:解码字符串时:
这是一个有效的例子:
//I make on purpose a bad choice for escape/delimiter characters
private static final char DELIMITER = '1';
private static final char ESCAPE = '2';
public static String encode(String s1, String s2){
StringBuilder sb = new StringBuilder();
subEncode(s1, sb);
sb.append(DELIMITER);
subEncode(s2, sb);
return sb.toString();
}
private static void subEncode(String s, StringBuilder sb) {
for(char c : s.toCharArray()) {
if(c == ESCAPE) {
sb.append(ESCAPE);
sb.append(ESCAPE);
}else if(c == DELIMITER) {
sb.append(ESCAPE);
sb.append(DELIMITER);
}else {
sb.append(c);
}
}
}
public static String[] decode(String encoded) {
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
StringBuilder currentSb = sb1;
char[] chars = encoded.toCharArray();
for(int i = 0; i< chars.length ; i++) {
if(chars[i] == ESCAPE) {
if(chars.length < i+2) {
throw new IllegalArgumentException("Malformed encoded String");
}
if(chars[i+1] == ESCAPE) {
currentSb.append(ESCAPE);
}else if(chars[i+1] == DELIMITER) {
currentSb.append(DELIMITER);
}
i++;
}else if(chars[i] == DELIMITER) {
currentSb=sb2;
}else {
currentSb.append(chars[i]);
}
}
return new String[]{sb1.toString(), sb2.toString()};
}
测试:
public static void main(String[] args) {
//Nominal case :
{
String s1 = "aaa";
String s2 = "bbb";
System.out.println("Encoded : " + encode(s1, s2));
System.out.println("Decoded" + Arrays.asList(decode(encode(s1,s2))));
}
//with bad characters :
{
String s1 = "111";
String s2 = "222";
System.out.println("Encoded : " + encode(s1, s2));
System.out.println("Decoded" + Arrays.asList(decode(encode(s1,s2))));
}
//with random characters :
{
String s1 = "a11a1";
String s2 = "1112bb22";
System.out.println("Encoded : " + encode(s1, s2));
System.out.println("Decoded" + Arrays.asList(decode(encode(s1,s2))));
}
}
输出:
Encoded : aaa1bbb
Decoded[aaa, bbb]
Encoded : 2121211222222
Decoded[111, 222]
Encoded : a2121a21121212122bb2222
Decoded[a11a1, 1112bb22]
另一种方式,使用以下格式格式化编码的字符串:
size_of_str_1:str1|size_of_str2:str2
示例:如果string1为'aa'且string2为'bbbb',则编码的String为:'2:aa | 4:bbbb'。
通过String #subString()解码它。 “硬”部分是解析字符串,直到你完成读取下一个字符串的大小。