例如,假设我想从数组中删除0个长度超过3个字节的所有连续段
byte a[] = {1,2,3,0,1,2,3,0,0,0,0,4};
byte r[] = magic(a);
System.out.println(r);
Run Code Online (Sandbox Code Playgroud)
结果
{1,2,3,0,1,2,3,4}
Run Code Online (Sandbox Code Playgroud)
我想在Java中执行类似正则表达式的操作,但是在字节数组而不是字符串上.
有什么东西可以帮助我内置(或者是否有一个好的第三方工具),还是我需要从头开始工作?
字符串是UTF-16,所以来回转换不是一个好主意?至少它浪费了大量的开销......对吧?
Ala*_*ore 26
byte[] a = {1,2,3,0,1,2,3,0,0,0,0,4};
String s0 = new String(a, "ISO-8859-1");
String s1 = s0.replaceAll("\\x00{4,}", "");
byte[] r = s1.getBytes("ISO-8859-1");
System.out.println(Arrays.toString(r)); // [1, 2, 3, 0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
我使用ISO-8859-1(latin1)因为,与其他任何编码不同,
范围中的每个字节都0x00..0xFF映射到有效字符,并且
这些字符中的每一个都具有与其latin1编码相同的数值.
这意味着字符串与原始字节数组的长度相同,您可以通过其数值与\xFF构造匹配任何字节,并且可以将结果字符串转换回字节数组而不会丢失信息.
我不会尝试以字符串形式显示数据 - 虽然所有字符都有效,但其中许多字符都不可打印.另外,避免在字符串形式下操纵数据; 你可能会意外地做一些转义序列替换或其他编码转换而没有意识到它.事实上,我不建议做这种事情,但这不是你问的.:)
此外,请注意,此技术不一定适用于其他编程语言或正则表达式.你必须单独测试每一个.
虽然我怀疑reg-ex是否适合这项工作,但如果你想使用它,我建议你只在字节数组上实现一个CharSequence包装器.像这样的东西(我直接写了这个,没有编译......但你明白了).
public class ByteChars
implements CharSequence
...
ByteChars(byte[] arr) {
this(arr,0,arr.length);
}
ByteChars(byte[] arr, int str, int end) {
//check str and end are within range here
strOfs=str;
endOfs=end;
bytes=arr;
}
public char charAt(int idx) {
//check idx is within range here
return (char)(bytes[strOfs+idx]&0xFF);
}
public int length() {
return (endOfs-strOfs);
}
public CharSequence subSequence(int str, int end) {
//check str and end are within range here
return new ByteChars(arr,(strOfs+str,strOfs+end);
}
public String toString() {
return new String(bytes,strOfs,(endOfs-strOfs),"ISO8859_1");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14577 次 |
| 最近记录: |