很久不更了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 {
private final int cacheSize;
private final LinkedHashMap map;
public LruCache(int cacheSize) {
this.cacheSize = cacheSize;
this.map = new LinkedHashMap(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();
}
}