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

一个正则表达式的问题

  •  
  •   k2wang · 339 天前 · 1679 次点击
    这是一个创建于 339 天前的主题,其中的信息可能已经有所发展或是发生改变。
    pattern1 = re.compile(r'\b(?:[^\.,]{2,}\s){2,}[^\.,]{2,}(\b,|$)')
    pattern2 = re.compile(r'\b(?:[\w]{2,}\s){2,}[\w]{2,}(\b,|$)')
    pattern1 与 2 的区别是[^\.,] vs [\w]

    数据量是 1000 条数据
    pattern1 几十秒还不出结果;
    pattern2 运行即拿到结果;

    为何两者性能差这么多,有人指点一下吗?
    17 条回复    2023-05-17 14:40:22 +08:00
    k2wang
        1
    k2wang  
    OP
       339 天前
    纠正:大概 4 万多条数据
    CEBBCAT
        2
    CEBBCAT  
       339 天前
    有没有尝试问一下 ChatGPT ?
    feedcode
        3
    feedcode  
       339 天前
    先问是不是?
    2 个不等价哦, "a bc" 这个 r'[\w]{2,}'就匹配不了
    k2wang
        4
    k2wang  
    OP
       339 天前
    @CEBBCAT 问了,它说匹配的字符集不同,但不知怎么优化,如果不使用[^]的话,就需要穷举一些常见的英文字符-:"(啥的,解析的准确率要差一点
    NCityXu
        5
    NCityXu  
       339 天前
    根据您提供的信息,可以看出 pattern1 和 pattern2 在正则表达式模式中的区别是[^\.,]与[\w]的使用。

    pattern1 中的[^\.,]表示匹配一个非逗号和句点的字符,而 pattern2 中的[\w]表示匹配一个单词字符(字母、数字或下划线)。这两个字符集的定义是不同的,可能会导致性能差异。

    性能差异可能有以下几个原因:

    字符集的复杂性:[^\.,]是一个更为复杂的字符集,它需要检查一个字符是否同时不是逗号和句点。这可能需要更多的计算资源和时间来确定是否匹配。
    匹配的字符数量:[^\.,]{2,}要求匹配至少两个连续的非逗号和句点字符,而[\w]{2,}要求匹配至少两个连续的单词字符。如果输入的数据中存在很长的连续字符序列,pattern1 可能需要更多的时间来找到匹配。
    数据的特征:具体的数据集特征也可能会影响正则表达式的匹配性能。如果数据中存在更多符合 pattern2 的模式,那么 pattern2 很可能会更快地找到匹配项。
    由于缺乏具体的数据示例,以上仅是一些可能导致性能差异的常见原因。实际上,性能差异的具体原因可能需要更详细的分析和测试来确定。如果您能提供更多相关信息或示例数据,我可以尝试给出更具体的解释。
    NCityXu
        6
    NCityXu  
       339 天前
    继续问就是了
    @k2wang
    roycestevie6761
        7
    roycestevie6761  
       339 天前
    @k2wang 以前遇到正则优化的时候,开发那边叫我用一下 hyperscan ,多模匹配这种,普通的正则根本不行。他们以前搞防火墙规则就用这个框架来做匹配,远远不止 4 万条数据。
    k2wang
        8
    k2wang  
    OP
       339 天前
    @feedcode 两者确实不一样哈,[^\.,]会匹配更多的字符,这正是我需要的,如果只是[\w],比较简单,无法满足需要。
    附 1 条示例数据:Qiu J., Chen Y., Tian Z., Guizani N., Du X., The security of internet of vehicles network: Adversarial examples for trajectory mode detection, IEEE Netw., 35, pp. 279-283, (2021);
    目的:识别出参考文献数据中的标题,The security of internet of vehicles network: Adversarial examples for trajectory mode detection

    为什么不匹配作者?
    因为作者的匹配规则更麻烦
    k2wang
        9
    k2wang  
    OP
       339 天前
    @NCityXu 谢谢,我再追问一下
    feedcode
        10
    feedcode  
       339 天前   ❤️ 2
    不考虑字符集\w 等于[a-zA-Z0-9_],没有必要写成[\w]
    [^\.,] 这个会匹配空格,然后你后面还有空格的匹配,regex 会做 backtrack ,影响性能
    k2wang
        11
    k2wang  
    OP
       339 天前
    @roycestevie6761 谢谢,我去了解下 hyperscan
    k2wang
        12
    k2wang  
    OP
       339 天前
    @feedcode 感谢,换成[^\.,\s] 之后,问题解决了,这个问题困扰我一天了
    gnawll
        13
    gnawll  
       339 天前
    (问 ChatGPT
    aloxaf
        14
    aloxaf  
       338 天前   ❤️ 2
    正则的灾难性回溯,经历过几年前 CF 全球大中断的程序员应该对其印象深刻
    别说几万行,运气不好一行数据就能把基于 NFA 的正则引擎搞挂
    https://regex101.com/r/BJbBXy/1
    gablic
        15
    gablic  
       338 天前
    两个模式之间的区别在于 pattern1 使用字符类[^\.,],它匹配任何不是句号或逗号的字符,而 pattern2 使用字符类[\w],它匹配任何单词字符(字母、数字或下划线)。

    pattern1 比 pattern2 慢的原因是[^\.,]匹配的字符比[\w]多。这意味着 pattern1 需要比 pattern2 更多的工作来找到匹配项。

    通常,在编写正则表达式时,使用最具体的字符类是一个好主意。这可以帮助提高性能并减少意外匹配的风险。

    希望这可以帮助您!如果您有其他问题,请告诉我。
    popvlovs
        16
    popvlovs  
       338 天前
    @aloxaf 没错,所以现在我基本都是用 hyperscan 了,因为不是基于回溯实现的,所以没有那么多的 corner case
    popvlovs
        17
    popvlovs  
       338 天前
    另外 hyperscan 限定了 x86 arch ,如果是 arm 可以参考这个 https://github.com/VectorCamp/vectorscan
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1317 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 17:33 · PVG 01:33 · LAX 10:33 · JFK 13:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.