Java 正则表达式的用法和一些具体实例

Java 正则表达式的用法和具体实例

目录

正则表达式常用符号:

Java 中正常表达式的应用:

实例1:匹配和替换字符

要求:

思考:

代码:

结果:

分析:

例子2:转化字符

要求:

思考:

代码:

结果:

总结:


 

正则表达式常用符号:

 

字符

说明

^

匹配输入字符串的开始位置。要匹配 "^" 字符本身,请使用 "\^"

$

匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "\$"

( )

标记一个子表达式的开始和结束位置。要匹配小括号,前面加 \ 

[ ]

用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,前面加 \ 

{ }

修饰匹配次数的符号。要匹配大括号,请使用 "\{" 和 "\}"

.

匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 "\."

?

修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "\?"

+

修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "\+"

*

修饰匹配次数为 0 次或任意次。要匹配 "*" 字符本身,请使用 "\*"

|

左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "\|"

{n}

修饰匹配次数为n次

{n,m}

修饰匹配次数为n次到m次

 

Java 中正常表达式的应用:

 

在实际的应用中,如何写pattern 是难点,需要熟悉正则表达式的常用符号,应用的话,需要了解其用法。

 

 

实例1:匹配和替换字符

 

要求:

根据字段的值(Map<String, Object> param)进行动态匹配后,再执行sql,得到结果

Sect* from xxx where field_name1=$param.paramName and field_name2=$global.STAFF_ID

思考:

 这边要进行替换的值是 $param.paramName,“$”开头,中间是“.”,要匹配的值是 逗号后面的值。

String pattern = "\\$[a-zA-Z_]*\\.([a-zA-Z_]*)";

“\\” 是转义, ()用于标记要匹配的值

 

代码:

public static void main(String[] args) {

    getMatchReplace();

}



public static void getMatchReplace()

{

    Map<String, Object> param = new HashMap<>();

    param.put("paramName", "lily");

    param.put("STAFF_ID", "1222");

    String content = "select * from xxx where field_name1 = $param.paramName and field_name2 = $global.STAFF_ID globals";

    String pattern = "\\$[a-zA-Z_]*\\.([a-zA-Z_]*)";

    Pattern p = Pattern.compile(pattern);

    Matcher m = p.matcher(content);

    StringBuffer sb = new StringBuffer();

    while (m.find())

    {

        String key = m.group(1);

        String value = MapUtils.getString(param, key);

        m.appendReplacement(sb, value == null ? "" : value);

    }

    System.out.println("appendTail before: "+ sb.toString());

    m.appendTail(sb);

    System.out.println("appendTail later: "+sb.toString());

}
 

结果:

appendTail before: select * from xxx where field_name1 = lily and field_name2 = 1222

appendTail later:  select * from xxx where field_name1 = lily and field_name2 = 1222  globals

 

分析:

正则表达式有分组概念:

   整个正则默认为0,而其余组号从“(”开始分配,第1组是第一个(和与其对应的)之间的正则内容。m.group(0)没有给参数,匹配的是0分组即整个正则;m.group(1)给了参数1,则是从整个正则匹配到的内容里面第一个()里面的内容,如例子中的([a-zA-Z_]*)。

 

appendReplacement方法: 

  sb是一个StringBuffer,replaceContext待替换的字符串,这个方法会把匹配到的内容替换为replaceContext,并且把从上次替换的位置到这次替换位置之间的字符串也拿到,然后,加上这次替换后的结果一起追加到StringBuffer里(假如这次替换是第一次替换,那就是只追加替换后的字符串)。

  比如上面的例子:value拿到lily后,appendReplacement 会找到匹配模式,会把$开头的$param.paramName找到逗号后面的paramName(m.group(1))替换成lily。

 

appendTail方法:

    sb是一个StringBuffer,这个方法是把最后一次匹配到内容之后的字符串追加到StringBuffer中。即把后面没检测过的字符串全加上去。

   比如执行appendTail之前,sb的值是“select * from account where field_name1 = lily and field_name2 = 1222”,加来appendTail把剩余的值追加后面。就变成了“select * from account where field_name1 = lily and field_name2 = 1222  globals”

 

例子2:转化字符

要求:

对查询的名字,转化特殊字符,查到值后,再将查询的名字转为回来。

 

思考:

 需要弄个转化,考虑把特殊字符16进制,前面加个标记,比如\u。转化的时候,再把十六进制替换回来,再匹配\u。

 

代码:

public static void main(String[] args) {
    String infos = convertString("1222#WOLF_KING@27");
    System.out.println("change infos: " + infos);
    System.out.println("rechange infos:  " + parseHexStr(infos));
}


// 转化部分特殊字符
public static String convertString(final String s) {
    if (Objects.isNull(s)) {
        throw new IllegalArgumentException("Invalid configName: null");
    }
    String t = StringUtils.replace(s, "/", "/");
    final int n = t.length();
    StringBuilder cc = new StringBuilder(50);
    for (int i = 0; i < n; i++) {
        final char c = t.charAt(i);
        if (!(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '-' || c == '_'
                || c == '.' || Character.isLetter(c))) {
            cc.append("/u" + StringUtils.leftPad(Integer.toHexString(c), 4, '0'));
        } else {
            cc.append(c);
        }
    }
    return cc.toString();
}

//将带有十六进制的内容转化成十进制
private static String parseHexStr(String hexValue) {
    String patternStr = "\\/u(\\d{4})";
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher = pattern.matcher(hexValue);
    String str = hexValue;
    while (matcher.find()) {
        String group0 = matcher.group();
        System.out.println("整个表达式: "+group0);
        String group1 = matcher.group(1);
        System.out.println("要匹配的值: "+group1);
        String str8 = StringUtils.leftPad(group1, 8, "0");
        System.out.println("往左边的内容补0,补齐到8位: "+str8);
        String replacement = String.valueOf((char) Integer.parseInt(str8, 16));
        System.out.println("把16进制的数字转化为要替换的内容: "+replacement);
        str = str.replaceAll(group0, replacement);
        System.out.println("替换后的值: "+str);
        System.out.println("==== next ===== ");
    }
    return str;
}

 

结果:

change infos: 1222/u0023WOLF_KING/u004027

整个表达式: /u0023

要匹配的值: 0023

往左边的内容补0,补齐到8位: 00000023

把16进制的数字转化为要替换的内容: #

替换后的值: 1222#WOLF_KING/u004027

==== next =====

整个表达式: /u0040

要匹配的值: 0040

往左边的内容补0,补齐到8位: 00000040

把16进制的数字转化为要替换的内容: @

替换后的值: 1222#WOLF_KING@27

==== next =====

rechange infos:  1222#WOLF_KING@27

 

后面再添加一些工作上遇到的例子

 

 

 

总结:

    在使用正则表达匹配和替换中,难点是pattern要怎么写,需要多熟悉,多练习。至于怎么用,了解分组的概念,替换基本就可以了。

    替换的方式有很多,根据要求可以使用不同的替换方式,比如springEL,StrSubstitutor等

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值