正面表达与回顾

 灬处男求包养灬 发布于 2023-02-06 13:19

我需要使用正则表达式以简单表达式查找所有操作.例如:

a+b*c/d

这里我们有3个操作.

    A + B

    公元前

    光盘

正则表达式\d.*[\+\-\*\/].*\d只返回两个匹配.

    A + B

    光盘

有没有办法找到所有的比赛?

1 个回答
  • 为了得到答案,我将以简单的步骤拆分它.

    1)匹配(数学)b

    为简单起见,我们将定义一个数字\d+,表示匹配一位或多位数.如果你想要一个更全面的正则表达式,你可以看一下这个答案.

    为匹配数学运算符,我们可能使用字符类[/*+-].如果你将字符放在一个字符类中,它们会失去正则表达式的意思,所以[.]只会匹配一个点.我们将使用不同的分隔符/,这样我们就不需要/在表达式中转义.连字符-通常用于定义字符范围,a-z但如果将其放在字符类的开头或结尾,则无需转义它.

    我们的正则表达式看起来像\d+\s*[/*+-]\s*\d+.\s*是否可以选择匹配一些空格.

    Online demo

    2)匹配(数学)b(数学)c(数学)d

    使用上面的模式时,你会发现它只匹配a (math) b,c (math) d而我们也希望匹配b (math) c.

    问题

    让我们举一个简单的例子1+2*3/4,当正则表达式引擎使用以下表达式时\d+\s*[/*+-]\d+:

    1+2*3/4
    ^^^ match and advance
    
    1+2*3/4
       ^ no match
    
    1+2*3/4
        ^^^ match and advance
    
    Nothing to do
    

    所以我们的问题是当引擎完成一个匹配时,它将从最后一个字符位置+ 1继续,而我们希望它从第一个数字的结尾继续.

    1+2*3/4
    ^^^ match and advance
    
    1+2*3/4
     ^ continue from here ?
    

    解决方案

    我们需要一个zerowidth前瞻断言(?=).例如a(?=b)意味着如果有ba,再搭配a所以a得到匹配的ab,但不是ac.这样做的好处是正则表达式引擎将从位置继续b而不是位置b+ 1.

    ab
    ^ match and continue
    
    ab
     ^ no match
    

    我们可能会利用它并使用捕获组将所需结果"转储"到一个组中:(?=(\d+\s*[/*+-]\d+)).

    1+2*3/4
    ^
    ^^^ match dump it in group 1 and continue
    
    1+2*3/4
     ^ no match
    
    1+2*3/4
      ^
      ^^^ match dump it in group 1 and continue
    
    1+2*3/4
       ^ no match
    
    1+2*3/4
        ^
        ^^^ match dump it in group 1 and continue
    
    1+2*3/4
         ^ no match
    
    1+2*3/4
          ^ no match
    
    The end
    

    Online demo

    3)出现了一个疯狂的问题

    到目前为止一直很好,但是当我们测试其他数字时,我们得到了一些奇怪的结果.输入是12+3,它给了我们两个结果在组1而不是一个12+32+3.什么原因 ?

    好吧,让我们一步一步看看:

    12+3
    ^
    ^^^^ match and dump it in group 1 and continue
    
    12+3
     ^
     ^^^ match and dump it in group 1 and continue
    
    12+3
      ^ no match
    
    12+3
       ^ no match
    

    啊看起来像一步推进并不是一件好事.所以我们需要匹配一个数字(?=(\d+\s*[/*+-]\d+))\d+!

    12+3
    ^^
    ^^^^ match and dump it in group 1 and continue
    
    12+3
      ^ no match
    
    12+3
       ^ no match
    

    对于TLDR来说有点迟,请使用某些语言~(?=(\d+\s*[/*+-]\d+))\d+~g修饰符.

    根据语言的不同,您可能无法使用自定义分隔符,这意味着您需要/在表达式中进行转义.

    Online demo

    2023-02-06 13:22 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有