我有类似下面的字符串(引号只显示可能有前导和尾随空格),我需要从字符串中提取数字,可以是整数或浮点数,负数或非负数。 / p>
" M0 0.5 l 20 0 0 20.34 -20 0q10 0 10 10 t 10 10 54.333 10 h -50 z"
提取数字后,我必须将它们与随机数相乘,以下函数产生。
-- returns a random float number between the specified boundaries (floats)
function random_in_interval(lower_boundary, upper_boundary)
return ((math.random() * (upper_boundary - lower_boundary)) + lower_boundary)
end
最后用正确的顺序重建带有字符和乘法数字的字符串。所有这一切都必须在Lua中发生,我不能使用任何外部库,因为这将在LuaTeX编译文档中使用。
不能更改字符的大小写,字符在它们之前和之后可能有也可能没有空格,但在输出中如果有的话会很好。我已经编写了一个辅助函数来添加字符前后的空格,但是当一个字符在它之前或之后有一个空格时,这将引入多个空格,这是我目前无法解决的。
-- adds whitespace before and after characters
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
-- remove leading and trailing whitespaces
if #padded_str ~= 0 then
padded_str = string.match(padded_str, "^%s*(.-)%s*$")
end
return padded_str
end
我不知道如何解析,修改字符串的数字部分,并以正确的顺序重建它,并在纯Lua中执行此操作而不使用任何外部库。
答案 0 :(得分:1)
试试这个。根据需要进行调整。
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))
答案 1 :(得分:0)
我无法想出比处理每个角色更好的东西,并决定它是一个数字(数字,小数点,负号)还是其他任何东西,并按照它行事。
-- returns a random float number between the specified boundaries (floats)
function random_in_interval(lower_boundary, upper_boundary)
return ((math.random() * (upper_boundary - lower_boundary)) + lower_boundary)
end
-- note: scaling is applied before randomization
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 -- scale and randomize
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
-- apply stuff
previous_was_number = false
end
end
end
return processed_str
end