代码之家  ›  专栏  ›  技术社区  ›  HBasiri

REGEX:PCRE原子组不工作

  •  0
  • HBasiri  · 技术社区  · 8 年前

    在我的PCRE正则表达式中,我使用原子组来减少回溯。

    <\/?\s*\b(?>a(?:bbr|cronym|ddress|pplet|r(?:ea|ticle)|side|udio)?|b(?:ase|asefont|d[io]|ig|lockquote|ody|r|utton)?|c(?:anvas|aption|enter|ite|ode|ol(?:group)?)|d(?:ata(?:list)?|[dlt]|el|etails|fn|ialog|i[rv])|em(?:bed)?|f(?:i(?:eldset|g(?:caption|ure))|o(?:nt|oter|rm)|rame(?:set)?)|h(?:[1-6r]|ead(?:er)?|tml)|i(?:frame|mg|nput|ns)?|kbd|l(?:abel|egend|i(?:nk)?)|m(?:a(?:in|p|rk)|et(?:a|er))|n(?:av|o(?:frames|script))|o(?:bject|l|pt(?:group|ion)|utput)|p(?:aram|icture|re|rogress)?|q|r[pt]|ruby|s|s(?:amp|ection|elect|mall|ource|pan|trike|trong|tyle|ub|ummary|up|vg)|t(?:able|body|[dhrt]|emplate|extarea|foot|head|ime|itle|rack)|ul?|v(?:ar|ideo)|wbr)\b
    

    REGEX101

    但在示例调试中,我看到 f 检查结束,它进一步为其他选择。我试着阻止它 f型 检查失败,因此它不会检查表达式的其余部分。发生了什么?

    2 回复  |  直到 8 年前
        1
  •  2
  •   jaytea    8 年前

    我假设您知道在这里使用regex是在做什么,因为可能有一个争论认为PCRE并不是以类似“树”的方式实现这种匹配的最佳方法。但我对此并不担心。

    使用条件语句的想法并不坏,但它以条件本身的形式添加了额外的步骤。此外,每个条件只能在两个方向分支。

    PCRE有一个称为“回溯控制动词”的功能,允许您精确地做您想要的事情。它们的控制水平各不相同,在这种情况下,我建议的控制水平最强:

    <\/?\s*\b(?>a(?:bbr|cronym|ddress|pplet|r(?:ea|ticle)|side|udio)?|b(?:ase|asefont|d[io]|ig|lockquote|ody|r|utton)?|c(?:anvas|aption|enter|ite|ode|ol(?:group)?)|d(?:ata(?:list)?|[dlt]|el|etails|fn|ialog|i[rv])|em(?:bed)?|f(*COMMIT)(?:i(?:eldset|g(?:caption|ure))|o(?:nt|oter|rm)|rame(?:set)?)|h(?:[1-6r]|ead(?:er)?|tml)|i(?:frame|mg|nput|ns)?|kbd|l(?:abel|egend|i(?:nk)?)|m(?:a(?:in|p|rk)|et(?:a|er))|n(?:av|o(?:frames|script))|o(?:bject|l|pt(?:group|ion)|utput)|p(?:aram|icture|re|rogress)?|q|r[pt]|ruby|s|s(?:amp|ection|elect|mall|ource|pan|trike|trong|tyle|ub|ummary|up|vg)|t(?:able|body|[dhrt]|emplate|extarea|foot|head|ime|itle|rack)|ul?|v(?:ar|ideo)|wbr)\b
    

    https://regex101.com/r/p572K8/2

    只需添加一个 (*COMMIT)

    (*提交) </ 如果找不到匹配项,则返回。

    要完全优化表达式,必须添加 在分支发生后的每一点。

    另一件事,你可以做的是尝试重新排序你的选择,以这样的方式,优先那些最常见的发现。这可能是优化过程中需要考虑的其他问题。

        2
  •  0
  •   CrafterKolyan    8 年前

    比赛 原子分组中的模式并保持它。 (来源: Confusion with Atomic Grouping - how it differs from the Grouping in regular expression of Ruby?

    因此,如果一个原子组内没有匹配项,它将遍历所有选项。 您可以改为使用条件:

    </?\s*\b(?级)?(?=a)一个(?:bbr | cronym |地址| pplet | r(?)?:ea | ticle)| side | udio?|(?(?=b)b(?:ase | asefont | d[io]| ig | lockquote | ody | r |按钮?|(?(?=c)c(?:anvas | aption | enter | ite | ode | ol(?)?:组)?)|(?(?=d)直径?:ata(?)?:列表?|【dlt】| el | etails | fn | ialog | i[rv])|(?(?=e)em(?:床上?|(?(?=f)f(?:我(?)?:eldset|g(?)?:标题(ure)?:nt | oter | rm)框架(?:套?)|(?(?=h)小时(?:[1-6r]| ead(?)?:呃?|tml)|(?(?=i)i(?:框架| mg | nput | ns?|(?(?=k)千桶重|(?(?=l)l(?:亚伯|埃根| i(?:nk)?)|(?(?=m)m(?:a(?)?:在| p | rk)等?:a | er))|(?(?=n)n(?:平均值?:帧|脚本)|(?(?=o)o(?:对象| l | pt(?:组| ion)| utput)|(?(?=p)p(?:阿拉姆?icture?re?罗杰斯?|(?(?=q)q |(?(?=r)r[pt]|(?(?=r)红宝石|(?(?=s)s |(?(?=s)秒(?:amp | ection | elect | mall | ource | pan | trike | trong | tyle | ub | ummary | up | vg)|(?(?=t)t(?:able | body |[dhrt]| emplate | extarea | foot | head | ime | itle | rack)|(?(?=u)ul吗?|(?(?=v)v(?:ar | ideo)| wbr)))))))))))))(b))(b)

    Regex101