根据未知分隔符(而不是分隔符的长度)进行字符串分割

我有一个相当奇特的问题。我的程序想要解码摩尔斯电码。

问题是,我需要处理 任何 字符。任何随机字符都应该被接受,只要它们符合我的系统并可以对应一个字母。这意味着,字母“Q”由“- -。-”表示,但是我的程序将接受任何字符字符串(由适当的newchar信号分隔),例如“dj ir j kw”(长长短长)作为Q。

存在失步的危险,因此我需要实现“new character”信号。我选择将其命名为“xxxx”,表示四个字母。对于空白符号,我选择了“xxxxxx”,即6个字符。

长话短说,我如何根据delimeter(4个连续符号)的长度将要解码的字符串拆分为可读取的字符,因为我无法确定 哪些 字母将组成newchar delimeter?

点赞
用户501459
用户501459

该问题表述不够清晰。

例如,你在这里展示了空格作为 Q 符号的不同部分之间的分隔符:

例如" dj ir j kw"(长长短长)

然后你说:

对于白色的,空格符号,我选择了“xxxxxx”,6个字符。

这是空白符号还是你在符号(如上面的 Q)中所使用的分隔符?你的帖子没有说清楚。

在这种情况下,就像往常一样,一个例子胜过千言万语。你应该展示一些可能的输入示例,并展示你想要如何解析它们。

如果你的意思是“dj ir j kw jfkl abpzoq jfkl dj ir j kw”应该解码为 “Q Q”,并且你只是想知道如何按其长度匹配令牌,那么...问题很简单。有无数种方法可以做到这一点。

在 Lua 中,我会进行两次处理。首先,将消息转换为仅包含连续字符块长度的字符串:

message = 'dj ir j kw jfkl abpzoq jfkl dj ir j kw'

message = message:gsub('(%S+)%s*', function(s) return #s end)

print(message) --> 22124642212

然后在数字 4 上拆分以获取每个组

for group in message:gmatch('[^4]+') do
    print(group)
end

它给您:

2212
6
2212

所以你可以将像这样的内容转换为:

function translate(message)
    local lengthToLetter = {
        ['2212'] = 'Q',
        [   '6'] = ' ',
    }
    local translation = {}
    message = message:gsub('(%S+)%s*', function(s) return #s end)
    for group in message:gmatch('[^4]+') do
        table.insert(translation, lengthToLetter[group] or '?')
    end
    return table.concat(translation)
end

print(translate(message))
2012-09-20 23:19:11
用户1516484
用户1516484

这段代码将字符串通过任意 len 次连续出现的 char(可以是字符或模式字符类(如 %s))或任何字符(即 .),分割成多个子串。

它通过在传递给 string.find 函数的模式中使用反向引用实现,例如 (.)%1%1%1 匹配任何字符重复四次。

剩下的部分只是普通的字符串分割器;这里 Lua 的奇特之处只在于模式的选择。

-- split str, using (char * len) as the delimiter
-- leave char blank to split on len repetitions of any character
local function splitter(str, len, char)
  -- build pattern to match len continuous occurrences of char
  -- "(x)%1%1%1%1" would match "xxxxx" etc.
  local delim = "("..(char or ".")..")" .. string.rep("%1", len-1)
  local pos, out = 1, {}
  -- loop through the string, find the pattern,
  -- and string.sub the rest of the string into a table
  while true do
    local m1, m2 = string.find(str, delim, pos)
    -- no sign of the delimiter; add the rest of the string and bail
    if not m1 then
      out[#out+1] = string.sub(str, pos)
      break
    end
    out[#out+1] = string.sub(str, pos, m1-1)
    pos = m2+1
    -- string ends with the delimiter; bail
    if m2 == #str then
      break
    end
  end
  return out
end

-- and the result?
print(unpack(splitter("dfdsfsdfXXXXXsfsdfXXXXXsfsdfsdfsdf", 5)))
-- dfdsfsdf, sfsdf, sfsdfsdfsdf
2012-09-21 02:51:50