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

Hub*_*bro 9 regex boost sublimetext2

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

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

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

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

dou*_*own 8

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

参考上述文件,它是,

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

?Ntrue-expression:false-expression

其中N是十进制数字.

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

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

  1. ?2总是假的,因为没有第二个捕获组.
  2. 第一个:是"特殊字符",true-expression其中表示空字符串
    • 如果我们假设true-expression不能被留为空,第一:解释为真和假表达之间的分隔符(用于血污/多汁详情,请阅读附录d).
    • 事实上,我们可以把任何我们想要的东西true-expression(只要:中间没有任何东西),因为?2永远不会评估为真.
  3. \u$1是的false-expression.

把两个和两个放在一起,我会走出去,然后说

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

这只是一种混淆的方式:

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

附录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>
Run Code Online (Sandbox Code Playgroud)

并且在替换的右侧使用不同的表达方式.

鉴于输入 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

基于此的一些初步结论(假设案例2,6,8是异常)

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

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