对于字符串Be there @ six.
为什么这样做:
str.gsub! /\bsix\b/i, "seven"
但是尝试替换@符号并不匹配:
str.gsub! /\b@\b/i, "at"
逃避它似乎也无效:
str.gsub! /\b\@\b/i, "at"
答案 0 :(得分:4)
这取决于\b
的解释方式。 \b
是一个“字边界”,如果\b
前面跟着字符,则会发生零长度匹配。单词字符仅限于[A-Za-z0-9_]
以及其他一些内容,但@
不是单词字符,因此\b
在它之前(以及在空格之后)将不匹配。空间本身不是边界。
如果您需要将@
替换为周围的空格,则可以在\b
之后捕获它并使用反向引用。对于零个或多个空格字符,这会使用\s*
捕获前面的空格。
str.gsub! /\b(\s*)@(\s*)\b/i, "\\1at\\2"
=> "Be there at six"
或者坚持使用空格,请使用\s+
代替\s*
。
str = "Be there @ six."
str.gsub! /\b(\s+)@(\s+)\b/i, "\\1at\\2"
=> "Be there at six."
# No match without whitespace...
str = "Be there@six."
str.gsub! /\b(\s+)@(\s+)\b/i, "\\1at\\2"
=> nil
此时,我们开始通过强制使用\b
来引入冗余。使用/(\w+\s+)@(\s+\w+)/
可以轻松完成,\b
匹配\w
字符后跟\s
空格。
如果您想将@
视为可能出现在开头或结尾的“字”,或者以空格为界,则可以使用\W
来匹配“非字”字符,与^$
锚点组合使用“或”管道|
:
# Replace @ at the start, middle, before punctuation
str = "@ Be there @ six @."
str.gsub! /(^|\W+)@(\W+|$)/, '\\1at\\2'
=> "at Be there at six at."
(^|\W+)
匹配字符串开头的^
或非字字符序列(如空格或标点符号)。 (\W+|$)
类似,但可以匹配字符串$
的结尾。
答案 1 :(得分:1)
\b
匹配单词边界,这是单词字符紧挨着非单词字符的位置。在您的字符串中,@
每边都有一个空格,@
或空格都不是单词字符,因此没有匹配。
比较
'be there @ six'.gsub /\b@\b/, 'at'
产生
'be there @ six'
(即没有变化)
但
'be there@six'.gsub /\b@\b/, 'at' # no spaces around @
产生
"be thereatsix"
另外
'be there @ six'.gsub /@/, 'at' # no word boundaries in regex
产生
"be there at six"