首页 > 编程语言 >【Java】Java提取${}占位符并组装对应值

【Java】Java提取${}占位符并组装对应值

时间:2022-10-02 13:34:49浏览次数:68  
标签:catalina Java String 符并 占位 base str data

目录

Java提取${}占位符并组装对应值

实现了一个${}装配工~

零、起因

最近写个JavaWeb项目,数据库相关的配置想放到properties文件中,用的H2,想直接内嵌,但是数据库文件位置想随程序移动,因为这个项目准备是放到U盘里随插随用的程序。然后配置URL时一开始用的是./data,它是在Tomcat bin目录下生成的,后面了解到有个私有的工作目录:${catalina.base},想我的数据库初始化程序也支持这个,直接加到H2的URL中jdbc:h2:${catalina.base}/data;报错,H2不支持。现在了解到可以通过System.getProperty("catalina.base")的方式获取到这个路径,那如何把URL中的${catalina.base}替换成System.getProperty("catalina.base")的值呢?

壹、想法

百度没得啥资料,我感觉可以通过正则匹配${},然后一个一个替换掉。

贰、实现

首先写了个正则表达式

\$\{[^}]+}

在菜鸟在线工具上测试通过
输入:

jdbc:h2:${catalina.base}/${catalina.base}work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;

输出:

共找到 2 处匹配:
${catalina.base}
${catalina.base}

然后在Java中实现了这个正则表达式的匹配

String str = "jdbc:h2:${catalina.base}/${catalina.base}work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;";
String pattern = "\\$\\{[^}]+}";

Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(str);
if(m.find()) {
    System.out.println(m.group());
    str = m.replaceFirst("第一个位置");
    System.out.println(str);
}

输出

${catalina.base}
jdbc:h2:第一个位置/${catalina.base}work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;

很好,加了个循环,依次替换掉后面的值

String str = "jdbc:h2:${catalina.base}/${catalina.base}work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;";
String pattern = "\\$\\{[^}]+}";

Pattern r = Pattern.compile(pattern);
int index = 0;
while (true) {
    Matcher m = r.matcher(str);
    if(m.find()){
        index++;
        System.out.println(m.group());
        str = m.replaceFirst("第" + index + "个位置");
        System.out.println(str);
    }else {
        break;
    }
}

输出

${catalina.base}
jdbc:h2:第1个位置/${catalina.base}work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;
${catalina.base}
jdbc:h2:第1个位置/第2个位置work/data;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CIPHER=AES;

好,真不戳,然后封装一下,替换的值由接口来决定,到时候重写这个接口就好了

package minuhy.ymz.WorkManage.Util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Auther: Minuhy
 * @Date: 2022/10/2 13:02
 * @Decsription: 装配 ${} 表达式的值
 */
public class StringAssembler {
    public interface Assemble {
        /**
         * 装配过程中需要通过${}里面的表达式找到对应的值
         * @param key ${}里面的表达式
         * @return ${}里面的表达式对应的值
         */
        String getStringByKey(String key);
    }

    /**
     * 装配 ${} 格式的字符串
     * @param str 原始字符串
     * @param assemble 装配过程中获取值的接口
     * @return 装配好之后的字符串
     */
    public static String assemble(String str, Assemble assemble) {
        String pattern = "\\$\\{[^}]+}";

        Pattern r = Pattern.compile(pattern);

        while (true) {
            Matcher m = r.matcher(str);
            if (m.find()) {
                String key = getKey(m.group());
                str = m.replaceFirst(assemble.getStringByKey(key));
            } else {
                break;
            }
        }

        return str;
    }

    /**
     * 获取 ${} 里面的值
     * @param g ${} 表达式
     * @return ${} 里面的值
     */
    public static String getKey(String g) {
        return g.substring(2, g.length() - 1);
    }
}

测试:

	@Test
    public void Test$Exp() {
        String str = "jdbc:h2:${key1}/${key2}work/data;";
        str = StringAssembler.assemble(str, key ->{
            System.out.println(key);
            if (key.equals("key1")) {
                return "第一个键";
            } else if (key.equals("key2")) {
                return "第二个键";
            }
            return "";
        });
        System.out.println(str);
    }

输出:

"C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -ea -......
key1
key2
jdbc:h2:第一个键/第二个键work/data;

Process finished with exit code 0

成功!

叁、总结

这个方式实现比较简单,但是复杂度应该是挺高的,后面可以尝试优化一下。

肆、参考文档

菜鸟正则表达式工具
问题:Java正则表达式匹配不到结果的解决

标签:catalina,Java,String,符并,占位,base,str,data
From: https://www.cnblogs.com/minuy/p/16748653.html

相关文章

  • java的方法定义(方法重载)!!!!!!
    方法的定义调用,!!!!!!![方法重载,(递归)]!!!!!!!一.方法System.out.println();是什么System是一个系统的类,out是一个对象:system下一个输出的对象,println()是一个方法调......
  • JavaScript中this指向哪儿?如何确定this?-前端面试进阶
    前言只要你踏入JavaScript的世界,那么你一定会遇到this关键词。有许多人所this是JavaScript中最复杂的东西之一,也有人说this其实很简单......但是事实确实,有许多工......
  • 【code基础】java 二进制和十进制互转
    十进制的int类型转变为字符串形式的二进制,如2->"10"Integer.toString(number,2);//十进制转换为二进制其中number为十进制的类型Integer.toBinaryString(number)//......
  • java多线程---4 线程同步介绍及不安全案例说明
    java多线程---4线程同步介绍及不安全案例说明线程同步并发:同一个对象被多个线程同时操作。处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这......
  • JavaScript中this指向哪儿?如何确定this?-前端面试进阶
    前言只要你踏入JavaScript的世界,那么你一定会遇到this关键词。有许多人所this是JavaScript中最复杂的东西之一,也有人说this其实很简单......但是事实确实,有许多......
  • JavaWeb----Vue+Axios+Json的数据请求
    详细资料:https://heavy_code_industry.gitee.io/code_heavy_industry/pro001-javaweb/lecture/chapter12/verse02.html《axios+vue发送普通参数请求》  《Json》 ......
  • JavaWeb-SMBMS(超市管理项目)
    目录SMBMS(超市管理项目)搭建项目准备工作登录功能实现登录功能优化登录拦截器密码修改优化密码修改使用Ajax用户管理模块实现1、获取用户数量2、获取用户列表3、获取角色......
  • JavaWeb-邮件收发
    目录邮件收发邮件收发原理Java发送邮件概述纯文本邮件带图片和附件的邮件JavaWeb发送邮件邮件收发电子邮件要在网络上实现邮件功能,必须要有专门的邮件服务器。这些邮件......
  • 【博学谷学习记录】超强总结,用心分享|Java基础分享-Redis基础简介
    1.1Redis简介1.2Redis资料1.2.1初步教程1.2.2其他教程2.1做为数据库与之比较2.2做为高速缓存与之比较2.3做为消息队列与之比较一、Redis基础知识1.1Redis......
  • JAVA_常用API
    MathSystem总结RuntimeObject......