提问人:Tyler Rick 提问时间:4/26/2019 最后编辑:Tyler Rick 更新时间:7/22/2019 访问量:230
如何在%r<内进行负向回溯...Ruby 中>分隔的正则表达式?
How to do a negative lookbehind within a %r<…>-delimited regexp in Ruby?
问:
我喜欢分隔符,因为它可以很容易地发现正则表达式的开头和结尾,而且我不必转义任何 .但似乎它们有一个其他分隔符所没有的不可逾越的限制?%r<…>
/
所有其他可以想象到的分隔符都可以正常工作:
/(?<!foo)/
%r{(?<!foo)}
%r[(?<!foo)]
%r|(?<!foo)|
%r/(?<!foo)/
但是当我尝试这样做时:
%r<(?<!foo)>
它给出了以下语法错误:
unterminated regexp meets end of file
好吧,它可能不喜欢它不是一对平衡的对,但你如何逃避它,让它喜欢它呢?
有什么需要逃避的吗?
根据 wikibooks.org:
任何单个非字母数字字符都可以用作分隔符 。 通过使用此表示法,可以出现通常的字符串分隔符 “ 和 ' 在字符串中未转义,但当然是您选择的新分隔符 确实需要逃脱。
%[including these], %?or these?, %~or even these things~
事实上,在这些示例中需要转义:
%r!(?<\!foo)!
%r?(\?<!foo)?
但是,如果这是唯一的问题,那么我应该能够像这样逃脱它并让它工作:
%r<(?\<!foo)>
但这会产生以下错误:
undefined group option: /(?\<!foo)/
所以也许不需要/不允许逃跑?wikibooks.org 列为例外之一:%<pointy brackets>
但是,如果您使用 或 作为分隔符,那么这些相同的分隔符 只要它们在平衡对中,就可以在字符串中显示为未转义
%(parentheses), %[square brackets], %{curly brackets}
%<pointy brackets>
平衡对有问题吗?
平衡对没有问题,只要您在正则表达式中做一些需要它们的事情,例如......
%r{(?<!foo{1})} # repetition quantifier
%r[(?<![foo])] # character class
%r<(?<name>foo)> # named capture group
但是,如果您需要在正则表达式中插入左侧分隔符({、[ 或 <)怎么办?逃避它,对吧?大多数时候,Ruby 似乎对转义的不平衡分隔符没有问题......
%r{(?<!foo\{)}
%r[(?<!\[foo)]
%r<\<foo>
只是当你尝试在“组选项”(我猜这就是这里的字符分类)中间这样做时,它不喜欢它:<!
(?
%r<(?\<!foo)>
# undefined group option: /(?\<!foo)/
那么,你如何做到这一点,让 Ruby 开心呢?(不更改分隔符)
结论
解决方法很简单。我将更改此特定正则表达式,以仅使用其他名称,例如。%r{…}
但问题仍然存在......
- 真的没有办法逃到这里吗?
<
- 真的有一些正则表达式根本不可能使用某些分隔符来编写吗?
%r<…>
- 是唯一存在此问题的正则表达式分隔符对(其中某些正则表达式在使用时无法写入)。如果您知道 / 的类似示例,请分享!
%r<…>
%r{…}
%r[…]
版本信息
这并不重要,因为这个语法可能没有改变,但我正在使用:
⟫ ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
参考:
答:
正如其他人所提到的,这似乎是基于这个角色与其他配对边界的不同之处的疏忽。
至于“这里真的没有办法逃<吗?”有办法......但你不会喜欢它:
%r<(?#{'<'}!foo)> == %r((?<!foo))
使用插值插入字符似乎有效。但鉴于有更好的选择,除非您打算将正则表达式拆分为多个部分,否则我会避免它......<
评论
%r<(?<=<)>
%r
.*>
<>
~