如何用不同的子串替换多个子串?

Tus*_*uss 5 java string replace

我从文本文件中获得了这一和弦.例如,

String chordLine = "C     G   Am  C";
String transposedChordLine;
Run Code Online (Sandbox Code Playgroud)

接下来,我需要使用两个参数,即转置的和弦和整数增量,使用下面的类将其chordLine转换为新transposedChordLineString.例如,transpose("C", 2)将返回D.

 public class Transposer{
    private int inc;
    private static ArrayList<String> keysSharp;
    private static ArrayList<String> keysFlat;

    Transposer(){
        keysSharp = new ArrayList<String>(Arrays.asList("C", "C#", "D", "D#","E", "F","F#", "G","G#", "A","A#", "B"));
        keysFlat = new ArrayList<String>(Arrays.asList("C", "Db", "D", "Eb","E", "F","Gb", "G","Ab", "A","Bb", "B"));
    }

    public String transpose(String chord,int inc){

        this.inc = inc;

        String newChord;

        if(chord.contains("/")){
            String[] split = chord.split("/");
            newChord = transposeKey(split[0]) + "/" + transposeKey(split[1]);
        }else
            newChord = transposeKey(chord); 
        return newChord;
    }

    private String transposeKey(String key){ // C#m/D# must pass C#m or D#
        String nKey, tempKey;

        if(key.length()>1){ 
            nKey = key.substring(0, 2);
            }
        else{ nKey = key; }


        int oldIndex, newIndex;

        if(key.contains("b")){
            oldIndex = (keysFlat.indexOf(nKey)>-1) ? keysFlat.indexOf(nKey) : keysFlat.indexOf(similarKey(nKey));
            newIndex = (oldIndex + inc + keysFlat.size())%keysFlat.size();
            tempKey = keysFlat.get(newIndex);
            nKey = (key.length() < 3) ? tempKey : key.replace(nKey, tempKey);
                //(nKey + key.substring(nKey.length(), key.length()));
        }
        else if(key.contains("#")){
            oldIndex = (keysSharp.indexOf(nKey)>-1) ? keysSharp.indexOf(nKey) : keysSharp.indexOf(similarKey(nKey));
            newIndex = (oldIndex + inc + keysSharp.size())%keysSharp.size();
            tempKey = keysSharp.get(newIndex);
            nKey = (key.length() < 3) ? tempKey : key.replace(nKey, tempKey);
        }
        else{
            nKey = nKey.substring(0, 1);
            oldIndex = (keysSharp.indexOf(nKey)>-1) ? keysSharp.indexOf(nKey) : keysSharp.indexOf(similarKey(nKey));
            newIndex = (oldIndex + inc + keysSharp.size())%keysSharp.size();
            tempKey = keysSharp.get(newIndex);
            nKey = (key.length() < 2) ? tempKey : key.replace(nKey, tempKey);
        }



        return nKey;
    }


    private String similarKey(String nKey) {
        String newKey;
        switch(nKey){
        case "Cb":
            newKey = "B";
            break;
        case "Fb":
            newKey = "E";
            break;
        case "E#":
            newKey = "F";
            break;
        case "B#":
            newKey = "c";
            break;
        default:
            newKey = null;
        }
        return newKey;
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在chordLine不丢失空格的情况下更换?增加2应该有transposedChordLine="D A Bm D"

这是我目前的尝试:

public static void main(String[] args) {

    String chordLine = "C      G            Am       C";
    String transposedChordLine;
    String normalize = chordLine.replaceAll("\\s+", " ");
    String[] split = normalize.split(" ");

    //System.out.println(normalize);


    Transposer tran = new Transposer();
    String[] temp = new String[split.length];

    for(int i=0 ; i<split.length ; i++){
        temp[i] = tran.transpose(split[i], 2);
        //System.out.println(split[i]);
        System.out.print(temp[i]);
    }

    transposedChordLine = chordLine.replaceAll([split], temp); //which is wrong

}
Run Code Online (Sandbox Code Playgroud)

dur*_*597 1

您的标记化非常不寻常(保留分隔符),您可能想自己做。基本上,如果您看到与音符匹配的标记,请将其传递给转置器。否则,传递一个空格。使用 while 循环来浏览笔记。这是执行此操作的代码:

private static final Transposer transposer = new Transposer();

public static void main(String[] args) {
  String chordLine = "C      G            Am       C";

  String transposed = transposeChordLine(chordLine);

  System.out.println(transposed);
}

private static String transposeChordLine(String chordLine) {
  char[] chordLineArray = chordLine.toCharArray();

  StringBuilder transposed = new StringBuilder();
  StringBuilder currentToken = new StringBuilder();

  int index = 0;
  while(index < chordLine.length()) {
    if(chordLineArray[index] == ' ') {
      transposed.append(' ');
      currentToken = processToken(transposed, currentToken);
    } else {
      currentToken.append(chordLineArray[index]);
    }
    index++;
  }

  processToken(transposed, currentToken);

  return transposed.toString();
}

private static StringBuilder processToken(StringBuilder transposed,
    StringBuilder currentToken) {
  if(currentToken.length() > 0) {
    String currentChord = currentToken.toString();
    String transposedChord = transposer.transpose(currentChord, 2);
    transposed.append(transposedChord);
    currentToken = new StringBuilder();
  }
  return currentToken;
}
Run Code Online (Sandbox Code Playgroud)

注意:您的代码存在一些风格问题。您可以在字段本身中初始化常量和弦映射;通过在构造函数中这样做,您会覆盖它们,做不必要的工作并可能导致问题,尤其是在多线程代码中。只需在字段声明中内嵌它们即可。将它们包装在 中也很好Collections.unmodifiableList,这样当代码运行时它们就无法更改,因此更容易避免意外犯错误。

另外,您不应该将inc变量保存在字段中,只需将其作为参数传递即可。这样,如果您两次使用同一个对象,它不会保留状态,因此是线程安全的。我知道这些事情对你当前的计划并不重要,但现在学习这些习惯是有好处的。这是修改后的Transposer类:

public class Transposer {
  private static final List<String> keysSharp = Collections.unmodifiableList(Arrays.asList("C", "C#", "D", "D#", "E",
        "F", "F#", "G", "G#", "A", "A#", "B"));
  private static final List<String> keysFlat = Collections.unmodifiableList(Arrays.asList("C", "Db", "D", "Eb", "E",
      "F", "Gb", "G", "Ab", "A", "Bb", "B"));

  public String transpose(String chord, int inc) {
    String newChord;

    if (chord.contains("/")) {
      String[] split = chord.split("/");
      newChord = transposeKey(split[0], inc) + "/" + transposeKey(split[1], inc);
    } else
      newChord = transposeKey(chord, inc);
    return newChord;
  }

  private String transposeKey(String key, int inc) { // C#m/D# must pass C#m or D#
    String nKey, tempKey;

    if (key.length() > 1) {
      nKey = key.substring(0, 2);
    } else {
      nKey = key;
    }

    int oldIndex, newIndex;

    if (key.contains("b")) {
      oldIndex = (keysFlat.indexOf(nKey) > -1) ? keysFlat.indexOf(nKey)
          : keysFlat.indexOf(similarKey(nKey));
      newIndex = (oldIndex + inc + keysFlat.size()) % keysFlat.size();
      tempKey = keysFlat.get(newIndex);
      nKey = (key.length() < 3) ? tempKey : key.replace(nKey, tempKey);
      // (nKey + key.substring(nKey.length(), key.length()));
    } else if (key.contains("#")) {
      oldIndex = (keysSharp.indexOf(nKey) > -1) ? keysSharp.indexOf(nKey)
          : keysSharp.indexOf(similarKey(nKey));
      newIndex = (oldIndex + inc + keysSharp.size()) % keysSharp.size();
      tempKey = keysSharp.get(newIndex);
      nKey = (key.length() < 3) ? tempKey : key.replace(nKey, tempKey);
    } else {
      nKey = nKey.substring(0, 1);
      oldIndex = (keysSharp.indexOf(nKey) > -1) ? keysSharp.indexOf(nKey)
          : keysSharp.indexOf(similarKey(nKey));
      newIndex = (oldIndex + inc + keysSharp.size()) % keysSharp.size();
      tempKey = keysSharp.get(newIndex);
      nKey = (key.length() < 2) ? tempKey : key.replace(nKey, tempKey);
    }

    return nKey;
  }

  private String similarKey(String nKey) {
    String newKey;
    switch (nKey) {
    case "Cb":
      newKey = "B";
      break;
    case "Fb":
      newKey = "E";
      break;
    case "E#":
      newKey = "F";
      break;
    case "B#":
      newKey = "c";
      break;
    default:
      newKey = null;
    }
    return newKey;
  }
}
Run Code Online (Sandbox Code Playgroud)