用正则表达式将所有和弦移调为字符串(java)

时间:2019-04-02 19:03:37

标签: java transpose chord

我有一个有效的C#和弦移调功能。我尝试将其重写为Java,但是由于某种原因,它似乎无效。也许Java正则表达式不支持lambda吗?

    private String transposeChord(String ChordRegel, Integer amount)
    {
        String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
        java.util.Map<String, String> normalizeMap = new java.util.HashMap<>();
        normalizeMap.put("Cb", "B");
        normalizeMap.put("Db", "C#");
        normalizeMap.put("Eb", "D#");
        normalizeMap.put("Fb", "E");
        normalizeMap.put("Gb", "F#");
        normalizeMap.put("Ab", "G#");
        normalizeMap.put("Bb", "A#");
        normalizeMap.put("E#", "F");
        normalizeMap.put("B#", "C");

        Pattern r = Pattern.compile("[CDEFGAB](b|#)?");
        Matcher match = r.matcher(ChordRegel);
        return ChordRegel.replaceAll("[CDEFGAB](b|#)?", match =>
        int i = (java.util.Arrays.asList(scale).indexOf(normalizeMap.containsKey(match.toString()) ? normalizeMap.get(match.toString()) : match.toString()) + amount) % scale.length;
        return scale[ i < 0 ? i + scale.length : i ];)
        ) ;
    }

这是有效的C#版本:

    private string transposeChord(string ChordRegel, int amount)
    {
        string[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
        string[] scale2 = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };
        var normalizeMap = new Dictionary<string, string>() { { "Cb", "B" }, { "Db", "C#" }, { "Eb", "D#" }, { "Fb", "E" }, { "Gb", "F#" }, { "Ab", "G#" }, { "Bb", "A#" }, { "E#", "F" }, { "B#", "C" } };
        var normalizeMap2 = new Dictionary<string, string>() { { "C#", "Db" }, { "D#", "Eb" }, { "E#", "F" }, { "F#", "Gb" }, { "G#", "Ab" }, { "A#", "Bb" }, { "B#", "C" }, { "Fb", "E" } };
        return new Regex("[CDEFGAB](b|#)?").Replace(ChordRegel, match =>
        {
            int i = 0; string NewKey = "";
            if (Mollen.Checked == true)
            {
                i = (Array.IndexOf(scale2, normalizeMap2.ContainsKey(match.Value) ? normalizeMap2[match.Value] : match.Value) + amount) % scale2.Length;
                NewKey = scale2[i < 0 ? i + scale2.Length : i];
            }
            else
            {
                i = (Array.IndexOf(scale, normalizeMap.ContainsKey(match.Value) ? normalizeMap[match.Value] : match.Value) + amount) % scale.Length;
                NewKey = scale[i < 0 ? i + scale.Length : i];
            }
            return NewKey;
        });
    }

1 个答案:

答案 0 :(得分:3)

为了获得最佳性能,我会在Java 11中这样做(请参阅最后的Java 8版本):

private static final String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
private static final Map<String, Integer> scaleIndex = new HashMap<>();
static {
    Map<String, String> normalizeMap = Map.of("Cb", "B", "Db", "C#", "Eb", "D#", "Fb", "E", "Gb", "F#", "Ab", "G#", "Bb", "A#", "E#", "F", "B#", "C");
    for (int i = 0; i < scale.length; i++)
        scaleIndex.put(scale[i], i);
    for (String s : normalizeMap.keySet())
        scaleIndex.put(s, scaleIndex.get(normalizeMap.get(s)));
}

private static String transposeChord(String chordRegel, int amount) {
    int normalizedAmount = (amount % scale.length + scale.length) % scale.length;
    return Pattern.compile("[CDEFGAB][b#]?").matcher(chordRegel).replaceAll(r ->
            scale[(scaleIndex.get(r.group()) + normalizedAmount) % scale.length]);
}

scaleIndex映射的构建仅完成一次,而normalizedAmount始终为0-11。

测试

for (int i = -12; i <= 12; i++)
    System.out.printf("%3d: %s%n", i, transposeChord("CbCC#", i));

输出

-12: BCC#
-11: CC#D
-10: C#DD#
 -9: DD#E
 -8: D#EF
 -7: EFF#
 -6: FF#G
 -5: F#GG#
 -4: GG#A
 -3: G#AA#
 -2: AA#B
 -1: A#BC
  0: BCC#
  1: CC#D
  2: C#DD#
  3: DD#E
  4: D#EF
  5: EFF#
  6: FF#G
  7: F#GG#
  8: GG#A
  9: G#AA#
 10: AA#B
 11: A#BC
 12: BCC#

更新: Java 8版本,未使用lambda:

private static final String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
private static final Map<String, Integer> scaleIndex = new HashMap<>();
static {
    String[] normalize = { "Cb", "B", "Db", "C#", "Eb", "D#", "Fb", "E", "Gb", "F#", "Ab", "G#", "Bb", "A#", "E#", "F", "B#", "C" };
    for (int i = 0; i < scale.length; i++)
        scaleIndex.put(scale[i], i);
    for (int i = 0; i < normalize.length; i += 2)
        scaleIndex.put(normalize[i], scaleIndex.get(normalize[i + 1]));
}

private static String transposeChord(String chordRegel, int amount) {
    int normalizedAmount = (amount % scale.length + scale.length) % scale.length;
    StringBuffer buf = new StringBuffer();
    Matcher m = Pattern.compile("[CDEFGAB][b#]?").matcher(chordRegel);
    while (m.find())
        m.appendReplacement(buf, scale[(scaleIndex.get(m.group()) + normalizedAmount) % scale.length]);
    return m.appendTail(buf).toString();
}