0

假设我有两个随机生成的字符串。

我可以做些什么来制作一个带有生成的两个字符串的字符串,同时能够拆分它们以获得原始的两个字符串以供以后使用?

例如,我有“[aweiroj\3aoierjvg0_3409”和“4093 w_/e9”。如何将这两个词附加到一个变量中,同时能够将它们拆分为原始的两个字符串?

我的问题是,我似乎找不到 .spit() 的正则表达式,因为这两个字符串可以有任何字符(alpabet、整数、\、/、空格...)。

编辑

我只是想到了一个可以使用它的真实案例。有时,通过网络(HTTP)发送纯文本比 xml 或 json 更好。宽带速度快的慢速服务器 - 使用 xml 或 json,宽带速度慢的快速服务器 - 使用纯文本。下面的答案可以防止纯文本注入。但是,这些方法没有进行基准测试或测试,我可能会在实际使用它们之前测试这些方法。

4

4 回答 4

9

简短的回答是:不要那样做。使用一个数组,或者一个具有两个数据成员的类,但是将这些字符串组合成一个字符串可能是个坏主意。

但是,如果您有一些真正晦涩难懂的用例,您可以:

  1. 创建一个足够独特的分隔符,例如"<<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());
    
  2. 有一个更简单的分隔符,如果存在于字符串中,您可以将其转义。

  3. 记住第一个字符串的长度并将其存储在统一的字符串中,然后是“长度结束”分隔符。

    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);
    

(这两个代码示例都是完全现成的并且未经测试。)

于 2013-09-10T15:25:53.247 回答
4

我将创建一个包含两个字符串并能够单独打印和组合打印它们的类。

这个只是扩展了 ArrayList 所以你不需要重新实现addget等等:

public class ConcatedString extends ArrayList<String>
{

    public String concated() {
        StringBuilder b = new StringBuilder();

        for (String string : this)
        {
            b.append(string);
        }

        return b.toString();
    }
}
于 2013-09-10T15:26:19.130 回答
3

如果这是某种(晦涩)类型的序列化问题,那么至少有一种明显的方法可以做到这一点。

使用某种编码对字符串进行编码(HTML 编码是一种简单易读的选择)。选择一个编码字符串不可能包含的字符,将其用作分隔符并将它们全部连接起来。

然后,要检索,按该字符分隔字符串,并使用您的初始方法反向解码子字符串。

于 2013-09-10T15:35:23.633 回答
2

如果您希望它在每种情况下都能正常工作,则需要定义 2 个特殊字符:

  • 分隔符
  • 一个转义字符。

1-Encoding :当您连接 2 String 时:

在这两个字符串中,

  • 用 2 个转义字符替换所有等于转义字符的字符
  • escape + delimiter替换所有等于分隔符的字符

然后将两个字符串与它们之间的分隔符连接起来。

2-解码:解码字符串时:

  • 如果当前字符是转义字符,而下一个字符也是转义字符,则只替换为一个转义字符并跳过 1 个字符。
  • 如果当前字符是转义字符,而下一个字符也是分隔符,则只替换为一个分隔符并跳过 1 个字符。
  • 如果当前字符是分隔符,那么您在 2 个原始字符串之间。

这是一个工作示例:

//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',则编码的字符串是:'2:aa|4:bbbb'。

您通过 String#subString() 对其进行解码。“硬”部分是解析字符串,直到您完成读取下一个字符串的大小。

于 2013-09-10T15:30:40.847 回答