【问题标题】:Replace multiple character with javascript用javascript替换多个字符
【发布时间】:2018-04-05 18:55:32
【问题描述】:

目前我只是用不同的东西替换一个角色,因为它是一张需要更改的乐谱,角色可能会有所不同。因此,我创建了一个 JavaScript 代码,如果在工作表上,它将替换所有这些字母。

这里出现了问题,如果我有字符 A 需要用 C 替换,然后在相同的 JavaScript 代码中 C 需要用 D 替换。因此 A 更改为 D 而不是 C。我需要替换每个字符每次操作一次,而不是将替换的文本与其他可能性进行比较。

到目前为止,这是我的代码:

function Dkoord() {
  $('[id^=harm] > text:nth-child(1) > tspan:nth-child(1)').text(function(i, text) {
    return text.replace('A', 'B').replace('A#', 'C').replace('Bb', 'C')
               .replace('B', 'C#').replace('C', 'D').replace('C#', 'D#')
               .replace('Db', 'Eb').replace('D', 'E').replace('D#', 'F')
               .replace('Eb', 'F').replace('F', 'G').replace('F#', 'G#')
               .replace('Gb', 'Ab').replace('G', 'A').replace('G#', 'A#')
               .replace('Ab', 'Bb');
});
}

正如您所见,C 正在更改为 D,但后来将 D 更改为 E,我只想对一个字符进行一次比较。我该怎么做。

【问题讨论】:

  • 将更改存储到临时变量并在完成后返回。
  • 先把C换成D,再把A换成C就可以解决你的问题了。
  • @Chris,你能给我一个关于如何临时变量一个函数然后执行它的例子吗?谢谢
  • 不是您要的,但从音乐上讲,您不能像那样移调音符/和弦,您必须考虑新键是什么。 (因为,例如,如果从 B 大调升调到 C# 大调,则 D# 音符必须变为 E# 而不是 F。)

标签: javascript replace


【解决方案1】:

使用一个正则表达式来匹配你想要替换的东西,像这样:

/[A-G](b|#)?/g

也就是说,匹配 A-G 中的任何字母,可选地后跟 b 或 #。

然后使用.replace() with a callback 查找匹配的内容并返回适当的替换。

function Dkoord() {
  var replacements = {
      'A': 'B', 'A#': 'C', 'Bb': 'C', 'B': 'C#', 'C': 'D', 'C#': 'D#',
      'Db': 'Eb', 'D': 'E', 'D#': 'F', 'Eb': 'F', 'F': 'G', 'F#': 'G#',
      'Gb': 'Ab', 'G': 'A', 'G#': 'A#', 'Ab': 'Bb'
  };

  $('[id^=harm] > text:nth-child(1) > tspan:nth-child(1)').text(function(i, text) {
    return text.replace(/[A-G](b|#)?/g, function(m) { return replacements[m]; });
  });
}

展开并运行以下 sn-p 以获得简化的演示:

function Dkoord(text) {
  var replacements = {
      'A': 'B', 'A#': 'C', 'Bb': 'C', 'B': 'C#', 'C': 'D', 'C#': 'D#',
 	  'Db': 'Eb', 'D': 'E', 'D#': 'F', 'Eb': 'F', 'F': 'G', 'F#': 'G#',
	  'Gb': 'Ab', 'G': 'A', 'G#': 'A#', 'Ab': 'Bb'
  };
    	  
  return text.replace(/[A-G](b|#)?/g, function(m) { return replacements[m]; });
}

console.log(Dkoord("A# B C D/F# G A"))

请注意,使用这样的查找对象还有一个优点,即您可以将其扩展为具有多个对象,以允许转置为不同的键。例如,如果从 B 大调到 C#,则应将 D# 更改为 E#,但如果从 F# 大调到 Ab,则应将 D# 更改为 F。

【讨论】:

  • 这太棒了,虽然你忘记了几个结尾),但代码对我来说很完美。非常感谢.. function Dkoord() { var replacements = { 'A': 'B', 'A#': 'C', 'Bb': 'C', 'B': 'C#', 'C': 'D', 'C#': 'D#', 'Db': 'Eb', 'D': 'E', 'D#': 'F', 'Eb': 'F', 'F': 'G', 'F#': 'G#', 'Gb': 'Ab', 'G': 'A', 'G#': 'A#', 'Ab': 'Bb'}; $('[id^=harm] > text:nth-child(1) > tspan:nth-child(1)').text(function(i, text) { return text.replace(/[A-G](b|#)?/, function(m) { return replacements[m]; }); }); }
  • 绝对是这里最好的方法。不错。
  • 对丢失的) 感到抱歉-我想我现在已经将它们重新编辑了。(在我的原始答案中,我从演示中的简化版本开始,以便我可以对其进行测试,并且然后我搞砸了把你的 jQuery 位放回去。)
  • P.S.谢谢@克里斯。还有 Henk - 请注意,我的替换地图是直接根据您问题中的代码改编的,但我只是注意到您错过了一些可能的起始注释,B#、E 和 E#。最好在你的实际项目中仔细检查这类事情。
  • 谢谢@nnnnnn,我还有一个问题:现在我的一行是 Cmaj7/A# C 被 D 正确替换,但 A# 根本没有改变。如何确保 / 后面的所有内容也被替换?再次感谢您的帮助。
【解决方案2】:

执行此操作的一种简单方法是将初始值替换为临时值,然后再次替换临时变量。

例如:

function Dkoord() {
  $('[id^=harm] > text:nth-child(1) > tspan:nth-child(1)').text(function(i, text) {
    return text.replace('A', 'b').replace('A#', 'c').replace('Bb', 'c')
               .replace('B', 'c#').replace('C', 'd').replace('C#', 'd#')
               .replace('Db', 'e_').replace('D', 'e').replace('D#', 'f')
               .replace('Eb', 'f').replace('F', 'g').replace('F#', 'g#')
               .replace('Gb', 'a_').replace('G', 'a').replace('G#', 'a#')
               .replace('Ab', 'b_').toUpperCase().replace(/[_]/g, "b");
  });
}

这将用小写的“正确”值替换您想要的文本,这将防止下一个管道替换已经替换的值。

完成后,您可以遍历字符串并将所有内容设置回大写。因此,只需在您最后一个 replace 之后添加它即可。

.toUpperCase().replace(/[_]/g, "b");

显然,您可以使用任何您想要的字符,只要它是唯一的。

演示

$("#btn").on("click", function() {
  $("#demo").text(function(i, text) {
    return text.replace('A', 'b').replace('A#', 'c').replace('Bb', 'c')
      .replace('B', 'c#').replace('C', 'd').replace('C#', 'd#')
      .replace('Db', 'e_').replace('D', 'e').replace('D#', 'f')
      .replace('Eb', 'f').replace('F', 'g').replace('F#', 'g#')
      .replace('Gb', 'a_').replace('G', 'a').replace('G#', 'a#')
      .replace('Ab', 'b_').toUpperCase().replace(/[_]/g, "b");
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b id="demo">AC#Eb</b>
<button id="btn">Convert</button>

【讨论】:

    【解决方案3】:

    试试这样的

     function Dkoord() {
    
         $('[id^=harm] > text:nth-child(1) > tspan:nth-child(1)').text(function(i, text) {
    
          return text.replace('Ab', 'Bb').replace('G#', 'A#').replace('G', 'A')
                .replace('Gb', 'Ab').replace('F#', 'G#').replace('F', 'G')
                .replace('Eb', 'F').replace('D#', 'F').replace('D', 'E')
                .replace('Db', 'Eb').replace('C#', 'D#').replace('C', 'D')
                .replace('B', 'C#').replace('Bb', 'C').replace('A#', 'C')
                .replace('A', 'B')
     });
     }
    

    【讨论】:

    • 这不能解决我的问题,C 到 D 和 D 到 E 只是一个例子。乐谱也可以从 Ab 到 Bb 开始,然后从 Bb 更改为 C,这也是我不想要的。一切都必须检查一次,如果选中则执行替换,并且不要在同一函数中再次检查。
    猜你喜欢
    • 2016-11-05
    • 1970-01-01
    • 2021-06-08
    • 2020-07-12
    • 2016-09-21
    • 2012-07-31
    • 1970-01-01
    • 2020-02-29
    • 2012-09-23
    相关资源
    最近更新 更多