使用Java正则表达式在字符串中分隔连续字符

时间:2019-04-03 09:58:29

标签: java regex

我正在尝试翻译字符串,并在任何大写字符之前加下划线。我最近的是:

out=in.replaceAll("([^_])([A-Z])","$1_$2");

但是使用"ABCDEF"它返回"A_BC_DE_F",我想是因为在考虑了“ AB”之后,它并没有看“ BC”,因为“ B”已经在前一场比赛中了。我当然可以应用两次,但是有一个更优雅的解决方案吗?

还有:

out=in.replaceAll("([A-Z])","_$1");

但它添加了前导"_"

Java 1.8(如果重要的话)

4 个答案:

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