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
sunmker
V2EX  ›  Python

请问如何判断多个关键词是否都不存在于指定的字符串中

  •  
  •   sunmker · 2019-10-26 17:07:54 +08:00 · 5711 次点击
    这是一个创建于 1890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这句话比较拗口,我举例解释一下。
    有一个字符串 a,若干关键词(“1”、“.”、“#@”、“qq”)
    我要判断是否这些关键词都不存在于字符串 a
    我的写法如下,但是我想问一下有没有更加简洁的写法。

    a='qwertddaivanoiasfvalfdpasfd'
    if '1' not in a and '.' not in a and '#@' not in a and 'qq' not in a:
        print('t')
    else :
        print('f')
    
    20 条回复    2019-11-01 21:20:05 +08:00
    moonheart
        1
    moonheart  
       2019-10-26 17:11:46 +08:00
    把这些关键词放到数组里去遍历判断
    eason1874
        2
    eason1874  
       2019-10-26 17:17:23 +08:00   ❤️ 1
    正则匹配不行吗?我记得可以的吧。
    CEBBCAT
        3
    CEBBCAT  
       2019-10-26 17:56:14 +08:00 via Android
    手写的话,应该循环 a_str,同时把关键词排序,然后二分匹配,可以节省一些时间。原来是 n*m,现在是 n*log m

    但还是建议看看正则可不可以解决
    CEBBCAT
        4
    CEBBCAT  
       2019-10-26 18:01:26 +08:00 via Android
    @CEBBCAT 我这是单字符的做法,字符串匹配有那个什么算法。不过这个问题应该请教 Livid。。。逃
    xuanbg
        5
    xuanbg  
       2019-10-26 18:01:56 +08:00
    两层循环正则匹配
    wzwwzw
        6
    wzwwzw  
       2019-10-26 18:09:10 +08:00
    a='qwertddaivanoiasfvalfdpasfd'
    strs = ["1",".","#@","qq"]

    results = [False for i in strs if i in a]
    if len(results) == 0:
    print("not in")
    else:
    print("in ")
    wzwwzw
        7
    wzwwzw  
       2019-10-26 18:10:22 +08:00
    a='qwertddaivanoiasfvalfdpasfd'
    strs = ["1",".","#@","qq"]
    results = [False for i in strs if i in a]
    if len(results) == 0:print("not in")
    else:print("in ")
    necomancer
        8
    necomancer  
       2019-10-26 18:54:09 +08:00
    key = [....]
    s = '....'
    for key in keys:
    ....if key in s:
    ........print('t')
    ........break
    else:
    ....print('f')
    Origami404
        9
    Origami404  
       2019-10-26 18:56:30 +08:00 via Android
    ac 自动机?
    ClericPy
        10
    ClericPy  
       2019-10-26 18:58:33 +08:00   ❤️ 1
    考虑性能就是 AC 自动机
    考虑原生就是正则表达式里的零宽断言
    uprightzy
        11
    uprightzy  
       2019-10-27 09:22:15 +08:00 via Android   ❤️ 1
    写一个函数能判断一个关键字是否在字符串里,然后把需要判断的关键字丢到一个 list 里,最后用 map(func,list)就能帮你把 list 中每个参数传进函数中执行,全部执行结果会被打包成一个 list 返回。
    mskf
        12
    mskf  
       2019-10-28 03:19:20 +08:00
    /1|\.|#@|qq/.test(a)
    mskf
        13
    mskf  
       2019-10-28 03:24:36 +08:00
    @mskf 前面少了个非,不过不影响,我觉得你是不是想问“都存在”?
    babyrjw
        14
    babyrjw  
       2019-10-28 09:39:45 +08:00
    这是关键词过滤吧,字典树,AC 自动机
    14cheese
        15
    14cheese  
       2019-10-28 19:07:45 +08:00 via iPhone
    是这样吗?

    a='qwertddaivanoiasfvalfdpasfd
    patterns = (‘a’, ‘b’)
    if all([ s not in a for s in patterns]):
    # do something
    pass
    sunmker
        16
    sunmker  
    OP
       2019-10-28 23:04:08 +08:00
    谢谢各位大佬提出建议,我尽最大努力都尝试了一下
    首先,正则可以实现我这个需求,我用 search 来实现「都不存在」,用 findall 来实现「都存在」

    其次,看了一下 AC 自动机,网上资料不多,我使用了一篇文章的代码实现,但是没有我想象中的代码那么简洁(即使仔细去一下代码优化)

    最后 @mskf 这个 Python 正则应该没有 test 的方法,js 里面是可以的

    ==========
    我刚开始是想问有没有我所不知道的高级语法糖可以实现这个功能,因为我觉得用 Python 要优雅,结果发现好像没有。但是集思广益,收获也很多,打开了我的思路,谢谢各位
    ClericPy
        17
    ClericPy  
       2019-10-29 00:43:54 +08:00
    @sunmker
    AC 自动机有现成的用 C 实现的, 直接 pip 装上用就好了, 自己写费那劲又不如 C 的快. 它的好处就是, blacklist 特别大的情况下, 性能非常不错, 做敏感词过滤 /替换的时候用的很爽.

    语法糖的话, 目测一般就是用函数式那俩 all 和 any, 以及 not any. 因为 Python3 里面这俩货都改生成器了, 所以内存和速度都有点优化

    零宽断言不见得特别有用, 不过好玩啊
    import re

    # 都存在
    print(re.search(r'^(?=.*中文)(?=.*英语).*$', '英语不如中文不'))
    print(re.search(r'^(?=.*中文)(?=.*英语).*$', '英语不如不'))
    print(re.search(r'^(?=.*中文)(?=.*英语).*$', '不如不'))
    # <re.Match object; span=(0, 7), match='英语不如中文不'>
    # None
    # None
    # 都不存在
    print(re.search(r'^(?!.*中文)(?!.*英语).*$', '英语不如中文不'))
    print(re.search(r'^(?!.*中文)(?!.*英语).*$', '英语不如不'))
    print(re.search(r'^(?!.*中文)(?!.*英语).*$', '不如不'))
    # None
    # None
    # <re.Match object; span=(0, 3), match='不如不'>
    solxnp
        18
    solxnp  
       2019-10-31 18:07:29 +08:00
    str = 'sdfjsdlkfjldgjldsgsdlg'
    keyword = ['s', 'c', 'b', 'o']
    result = all([i in str for i in keyword])
    solxnp
        19
    solxnp  
       2019-10-31 18:13:34 +08:00
    哦 看了下 你是想要都不存在 那改下就好
    str = 'sdfjsdlkfjldgjldsgsdlg'
    keyword = ['s', 'c', 'b', 'o']
    result = all([i not in str for i in keyword]) # 只要有一个存在 结果就为 False 全部不存在 结果为 True
    yucongo
        20
    yucongo  
       2019-11-01 21:20:05 +08:00
    kw = ("1", ".", "#@", "qq")
    all(map(lambda ele: ele not in a, kw))
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   989 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:06 · PVG 07:06 · LAX 15:06 · JFK 18:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.