@功能是如何高效实现的

现在很多网站都有@功能,weibo,qq等,对于一段文字中嵌入如@sharecqy这样的文本,如何高效的把它提取出来。

我的思路是,检测到@后,先在好友中查找,没找到,在到整个用户数据库中做最大匹配。

至于如何查询,听说有种叫字典树的结构,不知道是不是可以用来解决这个问题,了解的介绍下。

阅读 7k
3 个回答

目前我提供本站的处理方法,在textarea中进行事件绑定@,使用正则的方式将@符号匹配出来。然后将数据进行查找。

$("textarea[name=message]").atWho("@",{
tpl: "<li id='${uid}' data-value='${name}'>${name} <small>${spacenote}</small></li>",
'data':friend_list
});

数据,可以用sql将用户A的好友【关注】数量全部赛选出来,放入缓存,memcacedA。然后使用js json的方式去解析即可。memcacedA请注意时间。

最后数据提交,有正则去匹配出有 @xxxx 后的xxxx,进行sql查询,如果做了队列[缓存],用队列[缓存]是最优的方法。

PHP 的正则为:

$data = "@sharecqy @@@@@@@@@@@@@@ahc ";
preg_match_all("/@([^@]+?)([\s|:]|$)/is", $data, $matches);
print_r($matches);

以上是本站使用的@操作,我也在学习最高效的解决办法。

最后附上atme.js

http://ichord.github.io/At.js/

新手上路,请多包涵

OSCHINA @提到我 的处理代码 传送门

static Pattern referer_pattern = Pattern.compile("@([^@^\\s^:]{1,})([\\s\\:\\,\\;]{0,1})");//@.+?[\\s:]

/**
 * 处理提到某人 @xxxx
 * @param msg  传入的文本内容
 * @param referers 传出被引用到的会员名单
 * @return 返回带有链接的文本内容
 */
public static String _GenerateRefererLinks(String msg, List<Long> referers) {
    StringBuilder html = new StringBuilder();
    int lastIdx = 0;
    Matcher matchr = referer_pattern.matcher(msg);
    while (matchr.find()) {
        String origion_str = matchr.group();
        //System.out.println("-->"+origion_str);
        String str = origion_str.substring(1, origion_str.length()).trim();
        //char ch = str.charAt(str.length()-1);
        //if(ch == ':' || ch == ',' || ch == ';')
        //  str = str.substring(0, str.length()-1);
        //System.out.println(str);
        html.append(msg.substring(lastIdx, matchr.start()));

        User u = null;
        @SuppressWarnings("unchecked")
        List<User> users = User.INSTANCE.LoadList(User.CheckUsername(str)); 
        if(users != null && users.size()>0){
            u = users.get(0);
            for(User ref : users){
                if(ref.getThis_login_time()!=null && u.getThis_login_time()!=null && 
                        ref.getThis_login_time().after(u.getThis_login_time())){
                    u = ref;
                }
            }
        }
        if(u == null){
            u = User.GetByIdent(str);
        }

        if(u != null && !u.IsBlocked()){
            html.append("<a href='"+LinkTool.user(u)+"' class='referer' target='_blank'>@");
            html.append(str.trim());
            html.append("</a> ");
            if(referers != null && !referers.contains(u.getId()))
                referers.add(u.getId());
        }
        else{
            html.append(origion_str);
        }
        lastIdx = matchr.end();
        //if(ch == ':' || ch == ',' || ch == ';')
        //  html.append(ch);
    }
    html.append(msg.substring(lastIdx));
    return html.toString();
}

还有一款jquery插件:jquery-mentionsinput Github 传送门(没用过,暂不评价)

自动机解决:先用 strchr/memchr 找到 @,然后从下一个字符开始做最长匹配。自动机的功能比Trie树强,内存用量比Trie树小得多(小十几倍、甚至几十几百倍)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏