我正在尝试翻译字符串,并在任何大写字符之前加下划线。我最近的是:
out=in.replaceAll("([^_])([A-Z])","$1_$2");
但是使用"ABCDEF"
它返回"A_BC_DE_F"
,我想是因为在考虑了“ AB”之后,它并没有看“ BC”,因为“ B”已经在前一场比赛中了。我当然可以应用两次,但是有一个更优雅的解决方案吗?
还有:
out=in.replaceAll("([A-Z])","_$1");
但它添加了前导"_"
。
Java 1.8(如果重要的话)
答案 0 :(得分:4)
为什么要使用正则表达式?
String underscoreUppercase(String target){
StringBuilder b=new StringBuilder();
boolean first=true;
for(char c:target.toCharArray()){
if(Character.isUpperCase(c) && !first){//to ommit leading underscore
b.append('_');
}
first=false;
b.append(c);
}
return b.toString();
}
ABCDE
会产生A_B_C_D_E
答案 1 :(得分:4)
您可以将class MD5StreamCalculator: Stream {
MD5 md5Check;
public MD5StreamCalculator() {
md5Check = MD5.Create();
}
public string GetFinalMD5() {
md5Check.TransformFinalBlock(new byte[0], 0, 0);
byte[] hashBytes = md5Check.Hash;
return Convert.ToBase64String(hashBytes);
}
public override bool CanRead {
get {
return false;
}
}
public override bool CanSeek {
get {
return false;
}
}
public override bool CanWrite {
get {
return true;
}
}
public override long Length {
get {
throw new NotImplementedException();
}
}
public override long Position {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public override void Flush() {
}
public override int Read(byte[] buffer, int offset, int count) {
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin) {
throw new NotImplementedException();
}
public override void SetLength(long value) {
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count) {
md5Check.TransformBlock(buffer, 0, count, null, 0);
}
}
...
MD5StreamCalculator md5Stream = new MD5StreamCalculator();
targetBlockBlob.DownloadToStream(md5Stream);
Console.WriteLine("BASE64 = " + md5Stream.GetFinalMD5());
否定字符类放到非消耗性正向查找
[^_]
请注意,不需要使用捕获括号将整个使用模式括起来,s = s.replaceAll("(?<=[^_])[A-Z]","_$0");
后向引用表示整个匹配值。
请参见this Java demo:
$0
答案 2 :(得分:3)
您可以在此处使用正向超前
正则表达式:([A-Z])(?=([A-Z]))
,其中(?=([A-Z]))
是非消耗性正向预测
public static void main(String[] args) {
String in = "ABCDEF";
String out = in.replaceAll("([A-Z])(?=([A-Z]))", "$1_");
System.out.println(out);
}
答案 3 :(得分:2)
或者,您可以在每个大写字符处拆分字符串,然后使用下划线重新加入
String in = "ABCDEF";
String out = String.join("_", in.split("(?=\\p{Upper})"));
System.out.println(out);