Skip to content

Instantly share code, notes, and snippets.

@d-lua-stuff
Created September 2, 2020 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save d-lua-stuff/e4e5bb8a316bcaa28108201ab7734a46 to your computer and use it in GitHub Desktop.
Save d-lua-stuff/e4e5bb8a316bcaa28108201ab7734a46 to your computer and use it in GitHub Desktop.
Functions for extracting values from a JSON string with pattern matching. This is faster than using dkjson when only a few fields are needed. License: WTFPL
-- Extracts values from a JSON string with pattern matching
-- This is faster than using dkjson when only a few fields are needed
-- Use this only with trusted data sources! Limitations:
-- * Character escapes are not supported
-- * Field nesting is ignored
local find, gsub = string.find, string.gsub
---@param json string
---@param key string
---@param init number|nil
---@return string|nil, number|nil, number|nil
local function extractStringJsonValue (json, key, init)
local pattern = [["]] .. key .. [["%s*:%s*"([^"]*)"]]
local startIndex, endIndex, valueStr = find(json, pattern, init)
return valueStr, startIndex, endIndex
end
---@param json string
---@param key string
---@param init number|nil
---@return number|nil, number|nil, number|nil
local function extractNumberJsonValue (json, key, init)
local pattern = [["]] .. key .. [["%s*:%s*(-?[0-9.e-]+)]]
local startIndex, endIndex, valueStr = find(json, pattern, init)
return tonumber(valueStr), startIndex, endIndex
end
---@param json string
---@param key string
---@param init number|nil
---@return boolean|nil, number|nil, number|nil
local function extractBooleanJsonValue (json, key, init)
local pattern = [["]] .. key .. [["%s*:%s*([truefals]+)]]
local startIndex, endIndex, valueStr = find(json, pattern, init)
if valueStr == "true" then
return true, startIndex, endIndex
elseif valueStr == "false" then
return false, startIndex, endIndex
else
return nil
end
end
---@param extractJsonValue function
---@param json string
---@param key string
---@param stopAfterIndex number|nil
---@param stopAfterValue any|nil
---@return any[]
local function extractAllJsonValues (extractJsonValue, json, key, stopAfterIndex, stopAfterValue)
local values = {}
local valuesLen = 0
local jsonPos = 1
local value, valueStartIndex, valueEndIndex -- luacheck: ignore valueStartIndex -- unused
repeat
value, valueStartIndex, valueEndIndex = extractJsonValue(json, key, jsonPos)
if value ~= nil then
valuesLen = valuesLen + 1
values[valuesLen] = value
jsonPos = valueEndIndex + 1
end
if value == stopAfterValue then break end
if valuesLen == stopAfterIndex then break end
until value == nil
return values
end
---@param json string
---@param key string
---@param stopAfterIndex number|nil
---@param stopAfterValue string|nil
---@return string[]
local function extractAllStringJsonValues (json, key, stopAfterIndex, stopAfterValue)
return extractAllJsonValues(extractStringJsonValue, json, key, stopAfterIndex, stopAfterValue)
end
---@param json string
---@param key string
---@param stopAfterIndex number|nil
---@param stopAfterValue number|nil
---@return number[]
local function extractAllNumberJsonValues (json, key, stopAfterIndex, stopAfterValue)
return extractAllJsonValues(extractNumberJsonValue, json, key, stopAfterIndex, stopAfterValue)
end
---@param json string
---@param key string
---@param stopAfterIndex number|nil
---@param stopAfterValue boolean|nil
---@return boolean[]
local function extractAllBooleanJsonValues (json, key, stopAfterIndex, stopAfterValue)
return extractAllJsonValues(extractBooleanJsonValue, json, key, stopAfterIndex, stopAfterValue)
end
---@param json string
---@param key string
---@return string
local function deleteAllStringJsonValues (json, key)
local pattern = [[%s*"]] .. key .. [["%s*:%s*"[^"]*"%s*,?]]
return (gsub(json, pattern, ""))
end
---@param json string
---@param key string
---@return string
local function deleteAllNumberJsonValues (json, key)
local pattern = [[%s*"]] .. key .. [["%s*:%s*-?[0-9.e-]+%s*,?]]
return (gsub(json, pattern, ""))
end
---@param json string
---@param key string
---@return string
local function deleteAllBooleanJsonValue (json, key)
local pattern = [[%s*"]] .. key .. [["%s*:%s*[truefals]+%s*,?]]
return (gsub(json, pattern, ""))
end
return {
extractStringJsonValue = extractStringJsonValue,
extractNumberJsonValue = extractNumberJsonValue,
extractBooleanJsonValue = extractBooleanJsonValue,
extractAllStringJsonValues = extractAllStringJsonValues,
extractAllNumberJsonValues = extractAllNumberJsonValues,
extractAllBooleanJsonValues = extractAllBooleanJsonValues,
deleteAllStringJsonValues = deleteAllStringJsonValues,
deleteAllNumberJsonValues = deleteAllNumberJsonValues,
deleteAllBooleanJsonValue = deleteAllBooleanJsonValue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment