正则匹配以某字符开头,以某字符结尾

本文介绍了在Java中使用正则表达式去除字符串中特定格式的内容,例如QQ机器人开发中遇到的文件消息字符串。通过对比贪婪与非贪婪匹配,解决了从开头到结尾匹配的问题,实现了目标字符串的正确处理。并提到了String的replaceAll方法和Pattern对象的使用,以及在多线程环境下使用缓存的重要性。

前言

很久不更了0.0,现在公司里越来越没有了工作的激情,只剩下麻木的躯体和向往文艺的灵魂。

最近在整公司的QQ机器人开发,我们开发用到的是酷Q,用到的开发工具则是JCQ,然后因为对于图片或者文件消息等,接收到的字符串形如以下:

[CQ:image,file=50CB70BF5232E82C5E0D73184FAAE3EB.jpg]广东省方法[CQ:image,file=50CB70BF5232E82C5E0D73184FAAE3EB.jpg]dfsf[CQ:image,file=50CB70BF5232E82C5E0D73184FAAE3EB.jpg][CQ:image,file=50CB70BF5232E82C5E0D73184FAAE3EB.jpg]

这些东西对于目前公司的业务来说没有用处,所以想着用正则把他去掉,所以摸索了一段时间。

正文

一开始采用的正则:(以下为Java中的代码, \\ 是用来表示 \)

private static Pattern CQ_MSG_PATTERN = Pattern.compile("\\[CQ:.*\\]")

在这中正则的影响下,通过replace替换后的字符串为"",很显然不是"广东省方法dfsf"(目标结果),这个结果看着像是直接将最开头的部分和最结尾的匹配上了。同事提醒我说这是贪婪和非贪婪的问题,让我找个非贪婪的匹配,于是改成了以下:

private static Pattern CQ_MSG_PATTERN = Pattern.compile("\\[CQ:.*?\\]")

就完美的得到想要的结果了。

附录(随意看看)

一开始想着用Java的String的replace方法,毕竟它本身是支持正则的,但是想着用Pattern应该会省去Pattern对象的开销,于是看了一下replaceAll的源码:

public String replaceAll(String regex, String replacement) {
        return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}

噢,原来正则的replace是这么用的,于是我的替换如下:

    /**
     * @Description : 通过正则消除消息中的CQ标识
     *
     * @param content 接收到的内容
     * @return : 当通过正则替换后的字符串为空时,返回false;否则返回true
     * @author : 申劭明
     * @date : 2020/6/15 18:25
    */
    private boolean isBadMessage(String content) {
        content = CQ_MSG_PATTERN.matcher(content).replaceAll("");
        return StringUtil.isNullOrEmpty(content);
    }

另外,如果你也在用CQ开发的话,记着加一些必要的缓存措施,JCQ中多线程调用CQ的获取用户信息的方法会出问题,所以能缓存就加缓存吧。再附上一个Java封装的极简单的Lru实现:

/**
 * @author SSM
 * @date 2020/6/9 9:53
 */
public class LruCache<K, V> {
    private final int cacheSize;
    private final LinkedHashMap<K, V> map;

    public LruCache(int cacheSize) {
        this.cacheSize = cacheSize;
        this.map = new LinkedHashMap<K, V>(cacheSize, 0.75f, true){
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return cacheSize < this.size();
            }
        };
    }

    public V get(K key){
        return map.get(key);
    }

    public synchronized void put(K key, V value){
        map.put(key, value);
    }

    public synchronized void clear(){
        map.clear();
    }

    public synchronized int size(){
        return map.size();
    }

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值