Lua 使用根音和和弦名分割字符串

我需要将许多和弦名分割成键和和弦类型:

name = C
name = C#
name = Db
name = C#maj7b5
name = Cmaj7b5
name = Dbmaj7b5

因此,根总是一个单独的字母,带有 # 或 b,一个单独的字母,只带有 # 或 b,默认情况下,根将需要 = maj。

root = C
chord = maj
root = C#
chord = maj
root = Db
chord = maj
root = C#
chord = maj7b5
root = C
chord = maj7b5
root = Db
chord = maj7b5

我可以得到根名称:

name1 = string.match(name, "%a#")
name2 = string.match(name, "%ab")
name3 = string.match(name, "%a")

如果在 name1 和 name2 中得到空值,则根 = name3。只需要和弦名。

编辑:使用:

chord, pos = nil, 0
chord, p = string.match(region_name, "=%s+([^\n]+)()", pos)
if not p then end
pos = p
root, chord = string.match(region_name, "(%w[#b]?)(.*)$")
if not chord or #chord == 0 then chord = "maj" end
点赞
用户134758
用户134758
#!/usr/bin/env luajit

local text = [[
   name = C
   name = C#
   name = Db
   name = C#maj7b5
   name = Cmaj7b5
   name = Dbmaj7b5
]]

local chord, pos = nil, 0
while true do
   local chord, p = text:match("=%s+([^\n]+)()", pos)
   if not p then break end
   pos = p
   local root, chord = chord:match("(%w[#b]?)(.*)$")
   if not chord or #chord == 0 then chord = "maj" end
   print(("root = %s"):format(root))
   print(("chord = %s"):format(chord))
end

解释:

这个问题的难点在于找到正确的正则表达式。

在第一个正则表达式中:

text:match("=%s+([^\n]+)()", pos)

你只需要获取等号后面的任何内容。这个正则表达式还记住了匹配的最后位置,因此在下一次迭代中,你可以从最后的位置开始。如果没有匹配,最后的位置将是nil。在这种情况下,程序退出。

现在你得到了chord,你将它分成两个元素:

chord:match("(%w[#b]?)(.*)$")

第一部分获取一个字母(%w),然后是标记为可选的字符'#'或'b'。表达式的另一部分获取任何字符(.*),直到字符串的结尾。

2018-01-29 21:53:10