我喜欢使用%r<…>
作为分隔符,因为这样可以很容易地找到正则表达式的开头和结尾,并且我不必转义任何/
。但似乎它们有其他分隔符没有的难以克服的限制?
可以使用任何其他可能的分隔符:
/(?<!foo)/
%r{(?<!foo)}
%r[(?<!foo)]
%r|(?<!foo)|
%r/(?<!foo)/
但是当我尝试这样做时:
%r<(?<!foo)>
它会给出这个语法错误:
unterminated regexp meets end of file
好的,它可能不喜欢它不是一个平衡对,但是你如何转义它,使它喜欢呢?
需要转义吗?
根据 wikibooks.org:
任何单个非字母数字字符都可以用作分隔符,
%[包括这些],%?还是这些?,%~甚至这些~
。 使用此表示法,通常的字符串分隔符"和'可以出现在未转义的字符串中, 但是您选择的新分隔符确实需要转义。
确实,在这些示例中需要转义:
%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]
参考资料:
<>
配对。 - user557597~
! - Tyler Rick<>
是不合理的。我建议向 Ruby 提交错误报告,以便他们修复这个问题。对于()
等也是一样的,虽然我可以理解为什么他们认为这些只出现平衡的情况,但这并不是一个安全的假设(例如考虑%r([)])
)。 - ՕլՁՅԿ%r(...)
,因为我觉得它读起来像 MatchData 的“第 0 组”:$~[0]。 - Daniel