Module:Switch by pattern: Difference between revisions
return (capture) instead of key |
typo |
||
Line 12: | Line 12: | ||
local all = args["_returnall"] and args["_returnall"]~="" |
local all = args["_returnall"] and args["_returnall"]~="" |
||
local returnkeys = not(args[" |
local returnkeys = not(args["_returncaptures"] and args["_returncaptures"]~="") |
||
local sep = args["_sep"] and args["_sep"]~="" and args["_sep"] or "#" --should not be blank |
local sep = args["_sep"] and args["_sep"]~="" and args["_sep"] or "#" --should not be blank |
||
local outputsep = args["_outputsep"] or "#" --can be blank |
local outputsep = args["_outputsep"] or "#" --can be blank |
Revision as of 19:14, 24 April 2024
Unlike Switch parser function, this module matches any part of the input string or any Lua pattern in the input string. It returns the first match, or all matches separated by the chosen separator.
The module is used in {{Switch by pattern}} aka {{reSwitch}}.
Usage
{{#invoke:Switch by pattern|found_in|_input= |patterns1|patterns2|patterns3|keyA=patternsA |keyB=patternsB |_respectcase= |_returnall= |_sep= |_outputsep= |_default= }}
Module parameters:
|_input=
input string|key=patterns
returnkey
if any of thepatterns
is found in the input string;patterns
can be one or multiple strings separated by#
(or a separator given in|_sep=
); if unnamed parameters are used, the keys returned are their respective positions (1, 2, 3…)|_respectcase=
input string is lowercased by default, any value to avoid that|_returnall=
return the keys of all patterns that matched, separated by # or_outputsep
|_returncaptures=
instead of keys, return captures/matches|_sep=
which separator is used to separate patterns (defaults to#
); no pattern should contain this character or characters|_outputsep=
which separator to use to separate multiple keys returned when the_returnall
option is on (defaults to#
|_default=
which string to return if no patterns matched (defaults to empty string)
The string in patterns
can be a Lua pattern, or a word or part of a word (always interpreted as Lua patterns!), or several such patterns separated by #
, as in this#that#whatever
, which will be checked as aliases until the first match is found. (this is similar to regex matching this|that|whatever
, which is not available in Lua)
Note that all named parameters will have leading and trailing whitespace removed. This not only includes (|string key=pattern
) but also |2=pattern
and similar.
Examples
Matches parts of the input text
{{#invoke:Switch by pattern|found_in|_input=[[Animalia|beasts]]|dark gray=viru|pink=animal#beast|brown=fung}}
→ pink
{{#invoke:Switch by pattern|found_in|_input=[[Riboviria]] |dark gray=vir|pink=animal#beast |brown=fung}}
→ dark gray (keys may include whitespace)
With unnamed parameters, returning all matches
{{#invoke:Switch by pattern|found_in|_input=navy and red |red|green;lime;olive|azure;blue;navy|_returnall=yes|_sep=;|_outputsep=#}}
→ 1#3
With Lua patterns and Ustring patterns
{{#invoke:Switch by pattern|found_in|_input=name12|has two digits=%D%d%d$|has one digit=%D%d$}}
→ has two digits
Return captures
{{#invoke:Switch by pattern|found_in|_input=''[[Equus zebra]]''|''%[*(%u%a+ ?%a+)%]*''#''%[*(%u%a+ %b() ?%a+)%]*''|_respectcase=y|_returncaptures=y}}
→ Equus zebra (matched first patterns, two words){{#invoke:Switch by pattern|found_in|_input=''[[Equus (Hippotigris) hartmannae]]''|''%[*(%u%a+ ?%a+)%]*''#''%[*(%u%a+ %b() ?%a+)%]*''|_respectcase=y|_returncaptures=y}}
→ Equus (Hippotigris) hartmannae (matched second pattern:Word (word) word
){{#invoke:Switch by pattern|found_in|_input=''[[Anser cygnoides domesticus]]''|''%[*(%u%a+ ?%a+)%]*''#''%[*(%u%a+ %b() ?%a+)%]*''|_respectcase=y|_returncaptures=y}}
→ (no match, three words)
require('strict')
local p = {}
--will find either "human" or "homo" as part of the following _input, and return "orange"
--args = {_input="[[Homo sampiens|humans]]", ["pink"]="virus", ["green"]="plant", ["light gray"]="fung", ["orange"]="homo;human", _returnall="", _respectcase="", _sep=";"}
--aliases to search keys are separated by _sep, so _sep cannot be part of any key
--returns the first key found unless _returnall is nonempty, in which case it returns "all#keys#found" (for further processing?)
function p._found_in(args)
local skip_args = "#_input#_respectcase#_returncaptures#_returnall#_sep#_outputsep#_default#" --each key must be surrounded by #'s'
local res = {}
local all = args["_returnall"] and args["_returnall"]~=""
local returnkeys = not(args["_returncaptures"] and args["_returncaptures"]~="")
local sep = args["_sep"] and args["_sep"]~="" and args["_sep"] or "#" --should not be blank
local outputsep = args["_outputsep"] or "#" --can be blank
local lowercase = not (args["_respectcase"] and args["_respectcase"]~="") --lowercase input (but not search keys, they can be regex patterns)
local input = args["_input"] or ""
if input == "" then return "" end
if lowercase then input = mw.ustring.lower(input) end
for k,v in pairs(args) do
if not mw.ustring.match(skip_args, "#"..k.."#" ) then
local aliases = mw.text.split(v, sep, true)
for _,a in ipairs(aliases) do
if a~="" then
local match = mw.ustring.match(input, a)
if match then
local key_or_capture = returnkeys and k or match
if not all then return key_or_capture end
table.insert(res, key_or_capture)
break --first found alias
end
end
end
end
end
if #res>0 then return table.concat(res, outputsep) end --returnall was not blank
return args["_default"] or ""
end
function p.found_in(frame)
local args = frame:getParent() and frame:getParent().args
if not (args["_input"] and args["_input"]~="") then args = frame.args end
if args["_input"] and args["_input"]~="" then return p._found_in(args) end
return args["_default"] or ""
end
return p