diff --git a/apps/emqx_utils/src/emqx_placeholder.erl b/apps/emqx_utils/src/emqx_placeholder.erl index edf4123e4..0f677236d 100644 --- a/apps/emqx_utils/src/emqx_placeholder.erl +++ b/apps/emqx_utils/src/emqx_placeholder.erl @@ -48,9 +48,13 @@ -define(PH_VAR_THIS, '$this'). --define(EX_PLACE_HOLDER, "(\\$\\{[a-zA-Z0-9\\._]+\\})"). +%% To match any pattern starts with '$' and followed by '{', and closed by a '}' char: +%% e.g. for string "a${abc}bb", "${abc}" will be matched. +%% Note this is non-greedy matching +%% e.g. if "${{abc}}" is given, the "${{abc}" should be matched, NOT "${{abc}}". +-define(EX_PLACE_HOLDER, "(\\$\\{[^}]+\\})"). --define(EX_PLACE_HOLDER_DOUBLE_QUOTE, "(\\$\\{[a-zA-Z0-9\\._]+\\}|\"\\$\\{[a-zA-Z0-9\\._]+\\}\")"). +-define(EX_PLACE_HOLDER_DOUBLE_QUOTE, "(\\$\\{[^}]+\\}|\"\\$\\{[^}]+\\}\")"). %% Space and CRLF -define(EX_WITHE_CHARS, "\\s"). diff --git a/apps/emqx_utils/src/emqx_utils.app.src b/apps/emqx_utils/src/emqx_utils.app.src index 5900514dc..f8905b513 100644 --- a/apps/emqx_utils/src/emqx_utils.app.src +++ b/apps/emqx_utils/src/emqx_utils.app.src @@ -2,7 +2,7 @@ {application, emqx_utils, [ {description, "Miscellaneous utilities for EMQX apps"}, % strict semver, bump manually! - {vsn, "5.0.5"}, + {vsn, "5.0.6"}, {modules, [ emqx_utils, emqx_utils_api, diff --git a/apps/emqx_utils/test/emqx_placeholder_SUITE.erl b/apps/emqx_utils/test/emqx_placeholder_SUITE.erl index 81bf0853a..f813656f2 100644 --- a/apps/emqx_utils/test/emqx_placeholder_SUITE.erl +++ b/apps/emqx_utils/test/emqx_placeholder_SUITE.erl @@ -206,3 +206,53 @@ t_preproc_tmpl_deep(_) -> #{<<"${a}">> => [<<"1">>, "c", 2, 3.0, '${d}', {[<<"1.0">>], 0}]}, emqx_placeholder:proc_tmpl_deep(Tmpl1, Selected) ). + +t_proc_tmpl_arbitrary_var_name(_) -> + Selected = #{ + <<"中"/utf8>> => <<"1">>, + <<"中-1"/utf8>> => <<"1-1">>, + <<"-_+=<>,/?:;\"'\\[]|">> => 1, + <<"-_+=<>,">> => #{<<"/?:;\"'\\[]|">> => 2}, + <<"!@#$%^&*()">> => 1.0, + <<"d">> => #{ + <<"$ff">> => <<"oo">>, + <<"${f">> => <<"hi">>, + <<"${f}">> => <<"qq">> + } + }, + Tks = emqx_placeholder:preproc_tmpl( + << + "a:${中},a:${中-1},b:${-_+=<>,/?:;\"'\\[]|}," + "b:${-_+=<>,./?:;\"'\\[]|},c:${!@#$%^&*()},d:${d.$ff},d1:${d.${f}}"/utf8 + >> + ), + ?assertEqual( + <<"a:1,a:1-1,b:1,b:2,c:1.0,d:oo,d1:hi}">>, + emqx_placeholder:proc_tmpl(Tks, Selected) + ). + +t_proc_tmpl_arbitrary_var_name_double_quote(_) -> + Selected = #{ + <<"中"/utf8>> => <<"1">>, + <<"中-1"/utf8>> => <<"1-1">>, + <<"-_+=<>,/?:;\"'\\[]|">> => 1, + <<"-_+=<>,">> => #{<<"/?:;\"'\\[]|">> => 2}, + <<"!@#$%^&*()">> => 1.0, + <<"d">> => #{ + <<"$ff">> => <<"oo">>, + <<"${f">> => <<"hi">>, + <<"${f}">> => <<"qq">> + } + }, + Tks = emqx_placeholder:preproc_tmpl( + << + "a:\"${中}\",a:\"${中-1}\",b:\"${-_+=<>,/?:;\"'\\[]|}\"," + "b:\"${-_+=<>,./?:;\"'\\[]|}\",c:\"${!@#$%^&*()}\",d:\"${d.$ff}\",d1:\"${d.${f}\"}"/utf8 + >>, + #{strip_double_quote => true} + ), + ct:print("TKs:~p~n", [Tks]), + ?assertEqual( + <<"a:1,a:1-1,b:1,b:2,c:1.0,d:oo,d1:hi}">>, + emqx_placeholder:proc_tmpl(Tks, Selected) + ). diff --git a/changes/ce/perf-11399.en.md b/changes/ce/perf-11399.en.md new file mode 100644 index 000000000..42dac80bc --- /dev/null +++ b/changes/ce/perf-11399.en.md @@ -0,0 +1,8 @@ +Improved the placeholder syntax of rule engine. + +The parameters of actions support using placeholder syntax to +dynamically fill in the content of strings. The format of the +placeholder syntax is `${key}`. +Before this improvement, the `key` in `${key}` could only contain +letters, numbers, and underscores. Now the `key` supports any UTF8 +characters.