什么"(?x ::"意味着在Boost正则表达式替换中," x"是一个数字?

时间:2013-06-26 13:04:48

标签: regex boost sublimetext2

这是在Sublime Text 2的Ruby包中的一个片段文件中找到的Perl样式的正则表达式:

/(?:\A|_)([A-Za-z0-9]+)(?:\.rb)?/(?2::\u$1)/g

我知道它将像“some_class.rb”这样的文件名转换为“SomeClass”,但我无法弄清楚这部分的作用:(?2::。 Sublime Text 2使用boost作为其正则表达式,所以我检查了Boost-Extended Format String Syntax的文档,我发现boost支持格式字符串中的条件(f.inst。(?2(foo):(bar))),但你永远不需要两个冒号。此外,?2将指向第二个子表达式,但上面的表达式只匹配一个子表达式。出于这些原因,我不认为这是一个条件表达式。

感谢任何有启发性的答案。

2 个答案:

答案 0 :(得分:8)

首先,(?2::\u$1)替换方的///g 不是 Perl。这是Boost自己的扩展

参考上述文件,它是说,

  

角色'?'开始一个条件表达式,一般形式是:

     

?Ntrue-expression:false-expression

     

其中N是十进制数字。

     

如果子表达式N匹配,则计算true-expression并将其发送到输出,否则将评估false-expression并将其发送到输出。

基于此,让我们分析一下神秘的(?2::\u$1)

  1. ?2 总是为false,因为没有第二个捕获组。
  2. 第一个:true-expression中的“特殊字符”,表示空字符串
    • 如果我们假设true-expression不能为空,则第一个: 被解释为true和false表达式之间的分隔符(对于gory /多汁的细节,请阅读附录D )。
    • 事实上,我们可以把我们想要的任何东西作为true-expression(只要中间某处没有:),因为?2永远不会评估为真。
  3. \u$1false-expression
  4. 把两个和两个放在一起,我会走出去,然后说

    /(?:\A|_)([A-Za-z0-9]+)(?:\.rb)?/(?2::\u$1)/g
    

    只是一种混淆的方式:

    /(?:\A|_)([A-Za-z0-9]+)(?:\.rb)?/\u$1/g
    

    附录D:Sublime Text 2中的片段实验

    所以我用这个内容定义了一个Sublime Text 2片段

    <snippet>
        <content><![CDATA[
    snakecase: ${1:hello_world}
    camelcase: ${1/(?:\A|_)([A-Za-z0-9]+)(?:\.rb)?/(?2::\u$1)/g}
    ]]></content>
        <tabTrigger>convert</tabTrigger>
    </snippet>
    

    并为替换的右侧使用不同的表达方式。

    给定输入hello_world

    1. 如果右侧是(?2::\u$1),则返回HelloWorld
    2. 如果右侧是(?2:\u$1),则返回HW
    3. 如果右侧是(?2:$1),则不返回任何内容
    4. 如果右侧是(?2:::\u$1),则返回:Hello:World
    5. 如果右侧是(?1:\u$1),则返回HelloWorld
    6. 如果右侧是(?1::\u$1),则返回HW
    7. 如果右侧是(?1::$1),则不返回任何内容
    8. 如果右侧(?1:::\u$1)返回HW
    9. 如果右侧是(?1:::$1)则不返回任何内容
    10. 如果右侧是\u$1,则返回HelloWorld
    11. 基于此的一些初步结论(假设案例2,6,8是异常

      • 如果只有一个冒号(:)跟在数字后面,则忽略它(即它不被解释为true和false表达式之间的分隔符)。
      • 如果2个冒号(::)跟在数字后面,true-expression是一个空字符串(第二个:是分隔符)
      • 如果3个冒号(:::)跟在数字后面,true-expression是一个空字符串,false-expression以字面冒号开头(第二个:是分隔符)
      • 比较案例1和10,我对(?2::\u$1)\u$1的等同性的结论仍然有效。

      我说异常,因为\u$1$1相比表现得如此不同(除了捕获的子串的第一个字符之外的所有内容都消失了)

答案 1 :(得分:2)

也许替换字符串中有冒号,例如:\u$1是替换字符串。