java 正则表达式精确查找和替换指定字符
情形:
在复制模型的时候,要给名称加上“-复制”。一开始用的是 replace进行全部替换。在测试的时候,出现有元素名称跟模型名称是一样的,这样替换就有问题。这时候要改成正则去匹配和替换对应内容。
{
"flowModel": {
"flowMod": 502,
"flowType": 2,
"flowTypeName": "普通流程",
"flowTypeNameUs": "common",
"flowName": "流程表单模型A",
"flowNameUs": "流程表单模型A",
"fieldName": "流程表单模型A",
"state": "A"
},
"formModel": {
"formId": 108,
"flowMod": 502,
"flowName": "流程表单模型A",
"flowNameUs": "流程表单模型A",
"formName": "流程表单模型A",
"formNameUs": "流程表单模型A",
"fieldName": "流程表单模型A"
}
}
目标: 替换里面 flowName, flowNameUs,formName和formNameUs的名称
先处理一个
先写正则表单式:
String pattern ="\"flowName\""+ ":"+"\\s*\"" + modelName + "\"";
\\s*可以匹配0到多个空格
匹配到对应值后,用整个值进行替换
public static String matchReplaceName(String content, String modelName, String newModelName)
{
String pattern ="\"flowName\""+ ":"+"\\s*\"" + modelName + "\"";
System.out.println("pattern "+pattern);
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(content);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String group = m.group();
m.appendReplacement(sb, group.replace(modelName, newModelName));
}
m.appendTail(sb);
return sb.toString();
}
测试:
public static void main(String[] args) {
String content = initData();
String modelName = "流程表单模型A";
String newModelName = "流程表单模型A-复制";
content = matchReplaceName(content, modelName, newModelName);
System.out.println(content);
}
private static String initData(){
String data = "{\n" +
"\t\"flowModel\": {\n" +
"\t\t\"flowMod\": 502,\n" +
"\t\t\"flowType\": 2,\n" +
"\t\t\"flowTypeName\": \"普通流程\",\n" +
"\t\t\"flowTypeNameUs\": \"common\",\n" +
"\t\t\"flowName\": \"流程表单模型A\",\n" +
"\t\t\"flowNameUs\": \"流程表单模型A\",\n" +
"\t\t\"fieldName\": \"流程表单模型A\",\n" +
"\t\t\"state\": \"A\"\n" +
"\t},\n" +
"\t\"formModel\": {\n" +
"\t\t\"formId\": 108,\n" +
"\t\t\"flowMod\": 502,\n" +
"\t\t\"flowName\": \"流程表单模型A\",\n" +
"\t\t\"flowNameUs\": \"流程表单模型A\",\n" +
"\t\t\"formName\": \"流程表单模型A\",\n" +
"\t\t\"formNameUs\": \"流程表单模型A\",\n" +
"\t\t\"fieldName\": \"流程表单模型A\"\n" +
"\t}\n" +
"}";
return data;
}
结果:
pattern "flowName":\s*"流程表单模型A"
{
"flowModel": {
"flowMod": 502,
"flowType": 2,
"flowTypeName": "普通流程",
"flowTypeNameUs": "common",
"flowName": "流程表单模型A-复制",
"flowNameUs": "流程表单模型A",
"fieldName": "流程表单模型A",
"state": "A"
},
"formModel": {
"formId": 108,
"flowMod": 502,
"flowName": "流程表单模型A-复制",
"flowNameUs": "流程表单模型A",
"formName": "流程表单模型A",
"formNameUs": "流程表单模型A",
"fieldName": "流程表单模型A"
}
}
多个的:
表达式:
完成了单个,多个的用"|"进行分隔,先继续写单个的,然后拼接多一起
public static String matchReplaceName(String content, String modelName, String newModelName)
{
String condition = ":"+"\\s*\"" + modelName + "\"";
String pattern1 = "\"flowName\""+condition;
String pattern2 = "\"flowNameUs\""+condition;
String pattern3 = "\"formName\""+condition;
String pattern4 = "\"formNameUs\""+condition;
String pattern = pattern1 +"|"+pattern2+"|"+ pattern3 +"|"+pattern4;
System.out.println("pattern "+pattern);
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(content);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String group = m.group();
group = group.replace(modelName, newModelName);
m.appendReplacement(sb, group);
}
m.appendTail(sb);
return sb.toString();
}
最后可以把pattern的输出弄成一整行
测试结果:
pattern "flowName":\s*"流程表单模型A"|"flowNameUs":\s*"流程表单模型A"|"formName":\s*"流程表单模型A"|"formNameUs":\s*"流程表单模型A"
{
"flowModel": {
"flowMod": 502,
"flowType": 2,
"flowTypeName": "普通流程",
"flowTypeNameUs": "common",
"flowName": "流程表单模型A-复制",
"flowNameUs": "流程表单模型A-复制",
"fieldName": "流程表单模型A",
"state": "A"
},
"formModel": {
"formId": 108,
"flowMod": 502,
"flowName": "流程表单模型A-复制",
"flowNameUs": "流程表单模型A-复制",
"formName": "流程表单模型A-复制",
"formNameUs": "流程表单模型A-复制",
"fieldName": "流程表单模型A"
}
}
总结:
如果要精确替换指定字符,可以考虑正则,\\s*可以匹配0到多个空格 适用性会replace更好。先从单个开始入手,再逐个增加,验证,这样更能发现问题和调试。