add StrMatcher

This commit is contained in:
Looly 2021-03-05 22:37:41 +08:00
parent 047be5a1f8
commit 5646a1c3c0
3 changed files with 120 additions and 0 deletions

View File

@ -11,6 +11,7 @@
* 【core 】 IterUtil和CollUtil增加isEqualList方法issue#I3A3PY@Gitee
* 【crypto 】 增加PBKDF2issue#1416@Github
* 【core 】 增加FuncKeyMapissue#1402@Github
* 【core 】 增加StrMatcherissue#1379@Github
### Bug修复
* 【socket 】 修复Client创建失败资源未释放问题。

View File

@ -0,0 +1,103 @@
package cn.hutool.core.text;
import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 字符串模式匹配使用${XXXXX}作为变量例如
*
* <pre>
* pattern: ${name}-${age}-${gender}-${country}-${province}-${city}-${status}
* text: "小明-19-男-中国-河南-郑州-已婚"
* result: {name=小明, age=19, gender=, country=中国, province=河南, city=郑州, status=已婚}
* </pre>
*
* @author looly
* @since 5.6.0
*/
public class StrMatcher {
List<String> patterns;
public StrMatcher(String pattern) {
this.patterns = parse(pattern);
Console.log(this.patterns);
}
public Map<String, String> match(String text) {
final HashMap<String, String> result = MapUtil.newHashMap(true);
int from = 0;
String key = null;
int to;
for (String part : patterns) {
if (StrUtil.isWrap(part, "${", "}")) {
// 变量
key = StrUtil.sub(part, 2, part.length() - 1);
} else {
to = text.indexOf(part, from);
if (null != key && to > from) {
// 变量对应部分有内容
result.put(key, text.substring(from, to));
}
from = to + 1;
key = null;
}
}
if (null != key && from < text.length()) {
// 变量对应部分有内容
result.put(key, text.substring(from));
}
return result;
}
/**
* 解析表达式
* @param pattern 表达式使用${XXXX}作为变量占位符
* @return 表达式
*/
private static List<String> parse(String pattern) {
List<String> patterns = new ArrayList<>();
final int length = pattern.length();
char c = 0;
char pre;
boolean inVar = false;
StrBuilder part = StrUtil.strBuilder();
for (int i = 0; i < length; i++) {
pre = c;
c = pattern.charAt(i);
if (inVar) {
part.append(c);
if ('}' == c) {
// 变量结束
inVar = false;
patterns.add(part.toString());
part.clear();
}
} else if ('{' == c && '$' == pre) {
// 变量开始
inVar = true;
final String preText = part.subString(0, part.length() - 1);
if (StrUtil.isNotEmpty(preText)) {
patterns.add(preText);
}
part.reset().append(pre).append(c);
} else {
// 普通字符
part.append(c);
}
}
if (part.length() > 0) {
patterns.add(part.toString());
}
return patterns;
}
}

View File

@ -0,0 +1,16 @@
package cn.hutool.core.text;
import cn.hutool.core.lang.Console;
import org.junit.Test;
import java.util.Map;
public class StrMatcherTest {
@Test
public void matcherTest(){
final StrMatcher strMatcher = new StrMatcher("${name}-${age}-${gender}-${country}-${province}-${city}-${status}");
final Map<String, String> match = strMatcher.match("小明-19-男-中国-河南-郑州-已婚");
Console.log(match);
}
}