日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

极简模板语言实现

發布時間:2025/7/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 极简模板语言实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在項目中遇到這樣一個功能,需要用戶輸入一段帶參數的字符串模板,然后服務端根據一個上下文去解析它。查了一些資料發現了StrSubstitutor 這個小工具。其自帶例子如下:

Map valuesMap = HashMap();valuesMap.put("animal", "quick brown fox");valuesMap.put("target", "lazy dog");String templateString = "The ${animal} jumped over the ${target}.";StrSubstitutor sub = new StrSubstitutor(valuesMap);String resolvedString = sub.replace(templateString);

現在我想從一個二維表數據結構(List<Map<String, Object>>)中的某一行都去跑這么一個模板,這樣上面的例子就不需要了。我甚至還想對結果做個擴展,比如格式化什么的。通過查詢相關資料, 發現了StrLookup這個類。結合正則表達式,有了下面的實現

public class ExtraFormatLookup extends StrLookup {private static final String FMT = "fmt";private final List<Map<String, Object>> result;private final Map<String, MetricDO> metrics;ExtraFormatLookup(List<Map<String, Object>> result, Map<String, MetricDO> metrics) {this.result = result;this.metrics = metrics;}@Overridepublic String lookup(String s) {s = s.toLowerCase();String regex = "([^\\[.]+)(?:\\[(-?\\d+)])?(?:\\.([a-zA-z]+)(?::-(.*))?)?";Matcher matcher = Pattern.compile(regex).matcher(s);if (matcher.find()) {String key = matcher.group(1);String indexStr = matcher.group(2);String suffix = matcher.group(3);String defaultValue = matcher.group(4) == null ? "" : matcher.group(4);if (result == null || result.isEmpty()) {return defaultValue;}int index = 0;if (!Strings.isNullOrEmpty(indexStr)) {index = Integer.parseInt(indexStr);if (index < 0 - result.size() || index >= result.size()) {return defaultValue;}if (index < 0) {index = result.size() + index;}}String r = String.valueOf(result.get(index).getOrDefault(key, defaultValue));if (metrics.containsKey(key) && FMT.equalsIgnoreCase(suffix)) {r = CommonUtil.getValueFormatStr(metrics.get(key), r);}return r;} else {return "";}} }

測試代碼如下:

@Testpublic void lookup1() {List<Map<String, Object>> result = Lists.newArrayList(ImmutableMap.of("abc", "1111111"),ImmutableMap.of("abc", "222222"),ImmutableMap.of("abc", "33333", "def", "4444"));Map<String, MetricDO> metrics = Maps.newHashMap();metrics.put("abc", new MetricDO().setCode("abc").setType("abs").setPattern(",###,###"));StrSubstitutor sub = new StrSubstitutor(new ExtraFormatLookup(result, metrics));assertThat(sub.replace("test ${abc}"), Matchers.equalTo("test 1111111"));assertThat(sub.replace("test ${abc.fmt}"), Matchers.equalTo("test 1,111,111"));assertThat(sub.replace("test ${abc[0]}"), Matchers.equalTo("test 1111111"));assertThat(sub.replace("test ${abc[1]}"), Matchers.equalTo("test 222222"));assertThat(sub.replace("test ${abc[2]}"), Matchers.equalTo("test 33333"));assertThat(sub.replace("test ${abc[1].fmt}"), Matchers.equalTo("test 222,222"));assertThat(sub.replace("test ${abc[2].fmt}"), Matchers.equalTo("test 33,333"));assertThat(sub.replace("test ${def[2].fmt}"), Matchers.equalTo("test 4444"));assertThat(sub.replace("test ${def.fmt}"), Matchers.equalTo("test "));assertThat(sub.replace("test ${abc[-1].fmt}"), Matchers.equalTo("test 33,333"));assertThat(sub.replace("test ${abc[-2].fmt}"), Matchers.equalTo("test 222,222"));assertThat(sub.replace("test ${abc[-5].fmt}"), Matchers.equalTo("test "));assertThat(sub.replace("test ${abcd[-5].fmt:-efg}"), Matchers.equalTo("test efg"));assertThat(sub.replace("test ${abc[-789].fmt:-efg}"), Matchers.equalTo("test efg"));assertThat(sub.replace("test ${abcd[1111].fmt:-efg}"), Matchers.equalTo("test efg"));}

其實邏輯很簡單,就是通過正則表達式拿到要訪問的key,row的index,擴展方法字段以及默認值。后續要擴展也比較簡單,事先實現好方法然后增加支持的擴展字段就好了。

另外安利一個驗證Java正則表達式的網站https://www.freeformatter.com/java-regex-tester.html#ad-output

總結

以上是生活随笔為你收集整理的极简模板语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。