V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
shawshi
V2EX  ›  Python

V2EX 中 @ 一个人是怎么实现的?

  •  1
     
  •   shawshi ·
    shi1991 · 2016-10-21 11:24:30 +08:00 · 5659 次点击
    这是一个创建于 2990 天前的主题,其中的信息可能已经有所发展或是发生改变。
    前端的 @ 默认是如何实现的我已经知道,但是传递到后端 [ @xxx ] ,再次在页面上显示时是怎么处理的?
    第 1 条附言  ·  2016-10-21 13:24:34 +08:00

    最后补充(我揣测的 V2EX @ 功能的实现):

    • 前端使用 jquery.autocomplete 通过 参数 [match: /(^|\s)@(\w*)$/] ,当输入@时,触发下拉菜单显示。
    • 提交到后台,通过正则替换保存的文本内容。然后将带有 超链接 的评论存入到数据库。 [缺点:因为是html格式的数据,原生app那儿处理会有问题] 。

    正则替换的方法:

    def replaceContent(self, content):
            pattern = r'@(.*?) '
    
            def repl(match):
                if match.group(0):
                    _link_name = match.group(0)
                    link_name = re.findall(pattern, _link_name)
                    return '@<a href="/member/' + link_name[0] + '">' + link_name[0] + '</a> '
    
            content = re.sub(pattern, repl, content)
            return content
    

    需要内容替换直接掉这个方法就好了

    最后的最后 去了解一下 re.sub 中第二个参数

    32 条回复    2016-11-04 15:59:10 +08:00
    nanlong
        1
    nanlong  
       2016-10-21 11:34:52 +08:00
    正则替换
    helloccav
        2
    helloccav  
       2016-10-21 11:37:41 +08:00
    /\s@(.*?)\s/
    通过正则提取出主题、回复里出现过的所有用户名,传递到后端检查用户是否传在,传在就加上正超链接
    cheetah
        3
    cheetah  
       2016-10-21 11:42:50 +08:00
    存储的时候转为用户 id 存
    shawshi
        4
    shawshi  
    OP
       2016-10-21 11:50:00 +08:00
    @helloccav 在这个回复提交时做,还在展示列表的时候做?
    ChoateYao
        5
    ChoateYao  
       2016-10-21 11:53:57 +08:00
    测试下各种情况下的 @ 。

    第一种情况 @ChoateYao

    第二种情况 @ChoateYao
    Lcys
        6
    Lcys  
       2016-10-21 12:03:46 +08:00
    21grams
        7
    21grams  
       2016-10-21 12:06:00 +08:00
    在发帖的时候就已经替换了吧
    lrh3321
        8
    lrh3321  
       2016-10-21 12:06:05 +08:00
    页面上看到的应该只是正则替换,@不存在的 ID 仍然 会有下划线

    后台可能是检测下被 @ 的人是否存在,然后发通知过去吧
    lrh3321
        9
    lrh3321  
       2016-10-21 12:06:31 +08:00
    qiayue
        10
    qiayue  
       2016-10-21 12:09:06 +08:00
    被 @ 的提醒,是在提交的时候处理的
    前端显示的时候再次把所有 @ 转换成链接,也有可能会缓存格式化的内容,这样就省去每一次显示的时候格式化
    Lpl
        11
    Lpl  
       2016-10-21 12:10:06 +08:00 via Android
    Lpl
        12
    Lpl  
       2016-10-21 12:11:24 +08:00 via Android
    前端正则匹配,然后替换成链接。
    比如上边: https://www.v2ex.com/member/vvvvvvvv

    用户不存在就 404 ,存在就访问到相关页面了
    shawshi
        13
    shawshi  
    OP
       2016-10-21 12:15:46 +08:00
    @Lpl 应该是在将回复数据保存到数据库时 做了正则替换。他保存到数据库时就是 带 html 格式的回复内容。知乎直接使用的 div 做的富文本编辑器,他在前端 @完就会生成带有连接的 a 标签。
    wyntergreg
        14
    wyntergreg  
       2016-10-21 12:26:29 +08:00
    前端正文正则匹配

    提交后端队列提醒
    dong3580
        15
    dong3580  
       2016-10-21 13:26:08 +08:00
    压根不需要什么正则,就算你 @不存在的依然会显示链接。
    在打开 https://www.v2ex.com/member/xxxx 这个页面检查一次当前用户是否存在。
    至于收到提醒,插入一条记录呀,没有也插入呀,反正 @没有的人不存在。

    测试:

    @aaaaaaab 这里 带空格
    @aaaaaaab 这里 不带空格
    @这里 汉字
    @aaaaaaab,这里 带标点
    @aaaaaaab ,这里 带标点和空格
    laduary
        16
    laduary  
       2016-10-21 13:31:16 +08:00
    前端正则匹配,后端检测 ID 是否存在并且发送提醒吧。
    @laduary
    @4o4NotFound
    ruandao
        17
    ruandao  
       2016-10-21 13:42:31 +08:00
    @史蒂夫流口水了电风扇的饭了
    shawshi
        18
    shawshi  
    OP
       2016-10-21 13:42:38 +08:00
    @dong3580 后台需要用正则去处理你提交的内容。因为那个正则无法匹配到中文,所以那儿就没有显示超链接。 @不存在的人,因为后端没有验证处理。
    Immortal
        19
    Immortal  
       2016-10-21 14:18:07 +08:00
    看前面讨论的
    我插楼问个问题

    对于这种 @后的内容提取,比如用户名
    是前端提取后当,单独当一个参数给后台
    还是前端什么都不管 纯粹交给后台去正则处理
    ...主要考虑到如果 @功能用的人多 正则性能又低下的话
    StevenTong
        20
    StevenTong  
       2016-10-21 14:22:04 +08:00
    bumz
        21
    bumz  
       2016-10-21 18:55:30 +08:00
    后端正则,转成链接

    猜想证实:

    @aaaaaaaaaaaaa

    查看页面源码,发现一个不存在的用户被服务器加上链接。
    bumz
        22
    bumz  
       2016-10-21 19:00:16 +08:00
    @Lpl 不可能是前端做的,否则后端必须检查一遍数据的合法性,这和直接后端做没有区别,徒增复杂度,否则可被利用。
    bumz
        23
    bumz  
       2016-10-21 19:03:24 +08:00
    已证实,不是前端做的

    Lpl
        24
    Lpl  
       2016-10-21 19:04:51 +08:00 via Android
    @bumz
    这个后端解析是肯定解析了,不然没有办法发送站内通知。
    但是前端页面显示的时候也有可能会直接做匹配,然后替换成 a 链接,比如我下边 @一个不存在的人


    @乔布斯
    @不知道中文是否支持
    @如果中文支持,
    @那么应该就是在前端做替换了
    @如果不支持
    @那就是在后端解析的
    @因为注册时候不让用中文
    @testing
    Lpl
        25
    Lpl  
       2016-10-21 19:09:01 +08:00 via Android
    @Lpl 但是呢,也有可能是前端判定是否符合用户名规范之类的。

    所以,就看哪种会更有效率一点
    bumz
        26
    bumz  
       2016-10-21 19:16:35 +08:00
    @Lpl 后端替换的链接。

    Lpl
        27
    Lpl  
       2016-10-21 19:50:35 +08:00
    @bumz 嗯..是后端替换的
    IanPeverell
        29
    IanPeverell  
       2016-10-22 10:33:22 +08:00
    不过有一点比较有意思,就是列表只能展示出该主题下发过言的用户
    也许是前端储存了该帖内的参与人员信息,然后在正则替换也说不定
    sobigfish
        30
    sobigfish  
       2016-10-22 20:05:13 +08:00
    @IanPeverell 就在页面里啊,还用猜?
    $("#reply_content").textcomplete([{
    match: /(^|\s)@(\w*)$/,
    search: function (term, callback) {
    term = term.toLowerCase();
    var words= [.....
    honmaple
        31
    honmaple  
       2016-10-23 14:27:53 +08:00
    以前写过类似的功能
    ```
    def at_user(self, content):
    usernames = findall(r'@([\u4e00-\u9fa5\w\-]+)', content)
    ex_usernames = []
    for username in usernames:
    user = User.query.filter_by(username=username).first()
    if user is not None and username != current_user.username:
    ex_usernames.append(user.username)
    href = '/u/' + username
    u = '@' + username + ' '
    content = content.replace(u, '@<a href="%s">%s</a> ' %
    (href, username))
    usernames = list(set(ex_usernames))
    return content, usernames

    ```
    shawshi
        32
    shawshi  
    OP
       2016-11-04 15:59:10 +08:00
    @shawshi 测试 @功能
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1923 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 00:36 · PVG 08:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.