V2EX 中 @ 一个人是怎么实现的? - V2EX
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 5969 次点击
    这是一个创建于 3282 天前的主题,其中的信息可能已经有所发展或是发生改变。
    前端的 @ 默认是如何实现的我已经知道,但是传递到后端 [ @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  
    PRO
       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
    前端正则匹配,然后替换成链接。
    比如上边: 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
    压根不需要什么正则,就算你 @不存在的依然会显示链接。
    在打开 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
    不过有一点比较有意思,就是列表只能展示出该主题下发过言的用户
    也许是前端储存了该帖内的参与人员信息,然后在正则替换也说不定
    run2
        30
    run2  
       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     Solana     2923 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 13:29 PVG 21:29 LAX 06:29 JFK 09:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86