在Lua中,解析并修改字符串中的数字后重建该字符串

我有如下字符串(引号只显示可能会有前导和尾随空格),我需要从字符串中提取数字,这些数字可以是整数或浮点数、负数或非负数。

"   M0 0.5 l 20 0 0 20.34 -20 0q10 0 10 10 t 10 10 54.333 10 h -50 z"

提取数字后,我必须将它们乘以随机数字,下面的函数会生成随机浮点数。

-- 返回指定范围(浮点数)内的随机浮点数
function random_in_interval(lower_boundary, upper_boundary)
    return ((math.random() * (upper_boundary - lower_boundary)) + lower_boundary)
end

最后以正确的顺序重建带有字符和乘以的数字的字符串。另外,所有这些都必须在 Lua 中进行,我不能使用任何外部库,因为这将在 LuaTeX 编译的文档中使用。

字符的情况不能更改,字符可能具有空格或不具有空格,但在输出中最好有空格。我已经编写了一个辅助函数,在字符之前和之后添加空格,但是当一个字符之前或之后有一个空格时,这将引入多个空格,我目前无法解决。

-- 在字符之前和之后添加空格
function pad_characters(str)
    local padded_str = ""

    if #str ~= 0 then
        for i = 1, #str, 1 do
            local char = string.sub(str, i, i)

            if string.match(char, '%a') ~= nil then
                padded_str = padded_str .. " " .. char .. " "
            else
                padded_str = padded_str .. char
            end
        end
    end

    -- 删除前导和尾随空格
    if #padded_str ~= 0 then
        padded_str = string.match(padded_str, "^%s*(.-)%s*$")
    end

    return padded_str
end

我不知道如何解析、修改字符串的数字部分,并以正确的顺序重建它,在不使用任何外部库的情况下进行纯 Lua 工作。

点赞
用户1375010
用户1375010
我想不出比每个字符都要处理,再根据它是数字(数字、小数点、负号)还是其他字符来进行相应操作更好的方法。

-- 返回指定范围内的随机浮点数
function random_in_interval(lower_boundary, upper_boundary)
    return ((math.random() * (upper_boundary - lower_boundary)) + lower_boundary)
end

-- 注意:在随机化之前应用比例
function randomize_and_scale(str, scale_factor, lower_boundary, upper_boundary)
    local previous_was_number = false
    local processed_str = ""
    local number = ""

    for i = 1, #str, 1 do
        local char = string.sub(str, i, i)

        if previous_was_number then
            if string.match(char, '%d') ~= nil or
                char == "." then
                number = number .. char
            else -- 进行比例缩放和随机化
                number = number * scale_factor
                number = number * random_in_interval(lower_boundary, upper_boundary)
                processed_str = processed_str .. number .. char
                number = ""
                previous_was_number = false
            end
        else
            if string.match(char, '%d') ~= nil or
                char == "-" then

                number = number .. char
                previous_was_number = true
            else
                processed_str = processed_str .. char
                -- 应用相关内容
                previous_was_number = false
            end
        end
    end

    return processed_str
end
2014-08-23 19:18:19
用户107090
用户107090

尝试这个。根据需要进行适应。

s="   M0 0.5 l 20 0 0 20.34 -20 0q10 0 10 10 t 10 10 54.333 10 h -50 z"

print(s:gsub("%S+",function (x)
    local y=tonumber(x)
    if y then
        return y*math.random()
    else
        return x
    end

end))
2014-08-23 20:44:30