Lua:字符串中的换行

时间:2016-01-26 04:11:37

标签: string lua

我一直在研究一种格式化程序,它会使用一个长字符串并将其格式化为一系列在某个字符限制范围内断开的行。例如,他吃面包,每8个字符断开,会返回如下内容:

He eats
the
bread

这是因为“他吃”包含7个字符,而“面包”包含9个字符,所以它必须在“the”中断并继续“面包”。

由于之前其他成员的帮助,脚本本身一直运行得非常好。但是,现在我遇到了新的挑战。

我正在使用自由输入框来输入一系列线条。这是一个名为MUSHclient的程序,如果有人熟悉的话。 utils.editbox 会打开一个编辑器文本框,并允许自由格式,并将结果作为字符串返回。例如:

result = utils.editbox("What are you typing?")

将输入的响应保存到result string类型。我想正确地设置换行符,但我无法弄清楚如何做到这一点。如果我print(result),则返回如下内容:

This is the result of three separate paragraphs.

As you can see, there is a line break between each paragraph.

So the result contains line breaks, or control characters.

现在,我已设法使用以下代码推断各行,但不能推断其间的换行:

for line in result:gmatch("[^%c]+%c?") do 
  Send(note_wrap(line))
end

我如何推断换行符和文本内容?

修改作为参考,note_wrap功能如下:

function note_wrap(str, limit, indent, indent1)
  indent = indent or ""
  indent1 = indent1 or indent
  limit = limit or 79
  local here = 1-#indent1
  local last_color = ''
  return indent1..str:gsub("(%s+)()(%S+)()",
    function(sp, st, word, fi)
      local delta = 0
      local color_before_current_word = last_color
      word:gsub('()@([@%a])', 
        function(pos, c)
          if c == '@' then 
            delta = delta + 1 
          elseif c == 'x' then 
            delta = delta + 5
            last_color = word:sub(pos, pos+4)
          else                 
            delta = delta + 2 
            last_color = word:sub(pos, pos+1)
          end
        end)
      here = here + delta
      if fi-here > limit then
        here = st - #indent + delta
        return "\n"..indent..color_before_current_word..word
      end
    end)
end

此代码的原因是能够 @rHe吃@ x123面包,忽略颜色代码(由@< letter>或@ x< digits>表示)并返回上述结果:

He eats
the
bread

但插入颜色代码,然后返回:

@rHe eats
@x123the
bread

如果可以修改此项以识别新行并添加实际的新行,那将非常棒。

编辑2 尝试了保罗的解决方案,并没有按照我的要求去做。我可能不够清楚,所以我会尝试在此编辑中清除它。

当我输入自由格式框时,我希望信息完全按原样显示,但格式化为正确破坏并保持输入的换行符。例如,如果我在自由格式框中写这个:

Mary had a little lamb, little lamb, little lamb
Mary had a little lamb
It's fleece was white as snow

使用Paul的代码,并将字符串设置为79,我得到:

Mary had a little lamb, little lamb, little lamb

Mary had a little lamb

It's fleece was white as snow

这不是我想要的。我希望它能像它写的那样返回它,并根据需要打破它。因此,如果我有一个20个字符的限制,它会返回:

Mary had a little
lamb, little lamb,
little lamb
Mary had a little
lamb
It's fleece was
white as snow

如果我添加了手动换行符,我希望它能够尊重这些换行符,所以如果我在第一行之后点击返回两次,那么它在第一行下面也会有换行符。例如,如果我在自由格式框中写这篇文章,我希望它尊重每个新段落和每个正确的换行符。我希望这能解决问题。

1 个答案:

答案 0 :(得分:1)

我在我的代码中使用了类似的东西(假设\n是行分隔符):

local function formatUpToX(s, x, indent)
  x = x or 79
  indent = indent or ""
  local t = {""}
  local function cleanse(s) return s:gsub("@x%d%d%d",""):gsub("@r","") end
  for prefix, word, suffix, newline in s:gmatch("([ \t]*)(%S*)([ \t]*)(\n?)") do
    if #(cleanse(t[#t])) + #prefix + #cleanse(word) > x and #t > 0 then
      table.insert(t, word..suffix) -- add new element
    else -- add to the last element
      t[#t] = t[#t]..prefix..word..suffix
    end
    if #newline > 0 then table.insert(t, "") end
  end
  return indent..table.concat(t, "\n"..indent)
end
print(formatUpToX(result, 20))
print(formatUpToX("@rHe eats @x123the bread", 8, "  "))

cleanse函数删除了需要包含在字符串中的任何标记,但不需要计算限制。

对于您的示例,我得到以下输出(使用20作为第一个片段的限制,8作为第二个片段的限制:

This is the result 
of three separate 
paragraphs.

As you can see, 
there is a line 
break between each 
paragraph.

So the result 
contains line 
breaks, or control 
characters.

  @rHe eats 
  @x123the 
  bread