如何用JavaScript将Ultimate Guitar格式转为WorshipTools/ChordPro格式?
问题:将Ultimate Guitar和弦格式转为WorshipTools内联和弦格式
我计划用JavaScript编写代码,把ultimate guitar.com的和弦格式转换成worshiptools/chordpro格式,用于在GDevelop5中开发一款教会使用的WebApp。目前代码无法实现和弦与歌词的内联输出,当前输出效果如下:
[G] [D] [Em] Amazing grace, how sweet the sound [G] [D] [C] That saved a wretch like me
我使用的代码如下:
function convertUltimateGuitarToWorshipTools(ultimateGuitarText) { // Split input text into lines (songs may have multiple lines of chords/lyrics) const lines = ultimateGuitarText.split('\n'); const worshipToolsText = lines.map(line => { // This pattern finds the chords, which are typically words in uppercase or lowercase const chordPattern = /\b([A-G][#b]?(m|maj|min|sus|dim|aug)?)\b/g; // Replace each found chord with the WorshipTools format (i.e., [chord] ) return line.replace(chordPattern, (match, chord) => { return `[${chord}]`; }); }).join('\n'); // Join the lines back into a single string return worshipToolsText; } // Example Ultimate Guitar input (with chords above the lyrics) const ultimateGuitarText = ` G D Em Amazing grace, how sweet the sound G D C That saved a wretch like me `; // Convert the Ultimate Guitar text to WorshipTools format const worshipToolsText = convertUltimateGuitarToWorshipTools(ultimateGuitarText); // Output the converted text console.log(worshipToolsText);
我需要的正确输出效果为:
[G]Amazing grac[D]e, how swee[Em]t the sound [G]That saved [D]a wretch lik[C]e me
解决方案
原代码的核心问题是仅单独处理每一行,未将和弦行与对应歌词行合并。Ultimate Guitar的格式为和弦行+歌词行成对出现,因此需要按组处理这两行,将每个和弦插入到歌词的对应位置。
修改后的代码实现:
function convertUltimateGuitarToWorshipTools(ultimateGuitarText) { // 分割行并过滤空行 const lines = ultimateGuitarText.split('\n').filter(line => line.trim() !== ''); const result = []; // 按和弦行+歌词行的成对方式遍历 for (let i = 0; i < lines.length; i += 2) { const chordLine = lines[i]; const lyricLine = lines[i + 1]; if (!lyricLine) break; // 处理可能的奇数行情况 // 匹配所有和弦及其位置,返回[{chord: 'G', index: 0}, ...] const chordMatches = [...chordLine.matchAll(/(\b[A-G][#b]?(m|maj|min|sus|dim|aug)?\b)/g)]; const chordPositions = chordMatches.map(match => ({ chord: match[1], index: match.index })); // 从后往前插入和弦,避免位置偏移 let processedLyric = lyricLine; // 按位置倒序排列,防止插入前面的和弦影响后面的位置 chordPositions.sort((a, b) => b.index - a.index); chordPositions.forEach(({ chord, index }) => { // 确保索引不超过歌词长度 const insertIndex = Math.min(index, processedLyric.length); processedLyric = processedLyric.slice(0, insertIndex) + `[${chord}]` + processedLyric.slice(insertIndex); }); result.push(processedLyric); } return result.join('\n'); } // 测试示例 const ultimateGuitarText = ` G D Em Amazing grace, how sweet the sound G D C That saved a wretch like me `; const worshipToolsText = convertUltimateGuitarToWorshipTools(ultimateGuitarText); console.log(worshipToolsText);
代码说明
- 过滤空行:剔除无效空行,确保和弦行与歌词行能正确成对匹配
- 和弦位置解析:通过
matchAll获取每个和弦的内容与起始位置,精准定位和弦在歌词中的对应插入点 - 倒序插入:从后往前插入和弦,避免插入前序字符导致后续位置偏移,保证每个和弦插入到正确位置
- 边界处理:用
Math.min限制插入位置,防止超出歌词长度引发错误
内容的提问来源于stack exchange,提问作者MaxPKjj
相关产品推荐
相关产品推荐

