在 javascript 中我们可以执行以下操作:
var someString = `some ${myVar} string`
Run Code Online (Sandbox Code Playgroud)
我有以下lua代码,myVar是一个需要放在方括号中的数字:
splash:evaljs('document.querySelectorAll("a[title*=further]")[myVar]')
Run Code Online (Sandbox Code Playgroud)
Gre*_*een 15
符合您描述的功能是string.format:
splash:evaljs(string.format('document.querySelectorAll("a[title*=further]")[%s]', myVar))
Run Code Online (Sandbox Code Playgroud)
它不像 那样冗长${}。它更像是一个很好的旧的(并且令人讨厌的)sprintf。
我编写了 Python 字符串的模拟f'',它是一组可以隐藏在require文件中的函数。所以,如果您喜欢 Python 的f''字符串,这可能就是您正在寻找的。
(如果有人发现错误,请告知。)
与其他解决方案相比,它相当大,但如果您将大部分内容隐藏在库中,那么它的使用会更加紧凑和可读,IMO。
使用此库,您可以执行以下操作,例如:
require 'f_strings'
a = 12345
print(f'Number: {a}, formatted with two decimals: {a::%.2f}')
-- Number: 12345, formatted with two decimals: 12345.00
Run Code Online (Sandbox Code Playgroud)
请注意 Lua 格式化代码的使用string.format,以及格式说明符使用双冒号(而不是 Python 的单冒号),因为 Lua 对方法使用冒号。
我只从一个更大的库中提取了相关函数。尽管对于这个特定的用例可能可以进行一些优化,但我保留它们不变,因为它们是通用目的,并且也可能用于其他目的。
这是所需的库(放置在 Lua 库文件夹中的某个位置):
-- f_strings.lua ---
unpack = table.unpack or unpack
--------------------------------------------------------------------------------
-- Escape special pattern characters in string to be treated as simple characters
--------------------------------------------------------------------------------
local
function escape_magic(s)
local MAGIC_CHARS_SET = '[()%%.[^$%]*+%-?]'
if s == nil then return end
return (s:gsub(MAGIC_CHARS_SET,'%%%1'))
end
--------------------------------------------------------------------------------
-- Returns iterator to split string on given delimiter (multi-space by default)
--------------------------------------------------------------------------------
function string:gsplit(delimiter)
if delimiter == nil then return self:gmatch '%S+' end --default delimiter is any number of spaces
if delimiter == '' then return self:gmatch '.' end
if type(delimiter) == 'number' then --break string in equal-size chunks
local index = 1
local ans
return function()
ans = self:sub(index,index+delimiter-1)
if ans ~= '' then
index = index + delimiter
return ans
end
end
end
if self:sub(-#delimiter) ~= delimiter then self = self .. delimiter end
return self:gmatch('(.-)'..escape_magic(delimiter))
end
--------------------------------------------------------------------------------
-- Split a string on the given delimiter (comma by default)
--------------------------------------------------------------------------------
function string:split(delimiter,tabled)
tabled = tabled or false --default is unpacked
local ans = {}
for item in self:gsplit(delimiter) do
ans[#ans+1] = item
end
if tabled then return ans end
return unpack(ans)
end
--------------------------------------------------------------------------------
function copy(t) --returns a simple (shallow) copy of the table
if type(t) == 'table' then
local ans = {}
for k,v in next,t do ans[ k ] = v end
return ans
end
return t
end
--------------------------------------------------------------------------------
function eval(expr,vars)
--evaluate a string expression with optional variables
if expr == nil then return end
vars = vars or {}
assert(type(expr) == 'string','String expected as 1st arg')
assert(type(vars) == 'table','Variable table expected as 2nd arg')
local env = {abs=math.abs,acos=math.acos,asin=math.asin,atan=math.atan,
atan2=math.atan2,ceil=math.ceil,cos=math.cos,cosh=math.cosh,
deg=math.deg,exp=math.exp,floor=math.floor,fmod=math.fmod,
frexp=math.frexp,huge=math.huge,ldexp=math.ldexp,log=math.log,
max=math.max,min=math.min,modf=math.modf,pi=math.pi,pow=math.pow,
rad=math.rad,random=math.random,randomseed=math.randomseed,
sin=math.sin,sinh=math.sinh,sqrt=math.sqrt,tan=math.tan,
tanh=math.tanh}
for name,value in pairs(vars) do env[name] = value end
local a,b = pcall(load('return '..expr,nil,'t',env))
if a == false then return nil,b else return b end
end
--------------------------------------------------------------------------------
-- f'' formatted strings like those introduced in Python v3.6
-- However, you must use Lua style format modifiers as with string.format()
--------------------------------------------------------------------------------
function f(s)
local env = copy(_ENV) --start with all globals
local i,k,v,fmt = 0
repeat
i = i + 1
k,v = debug.getlocal(2,i) --two levels up (1 level is this repeat block)
if k ~= nil then env[k] = v end
until k == nil
local
function go(s)
local fmt
s,fmt = s:sub(2,-2):split('::')
if s:match '%b{}' then s = (s:gsub('%b{}',go)) end
s = eval(s,env)
if fmt ~= nil then
if fmt:match '%b{}' then fmt = eval(fmt:sub(2,-2),env) end
s = fmt:format(s)
end
return s
end
return (s:gsub('%b{}',go))
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18613 次 |
| 最近记录: |