ruby-on-rails - 为什么正则表达式不能匹配@符号?

标签 ruby-on-rails ruby regex

对于字符串Be there @ Six.

为什么这有效:

str.gsub! /\bsix\b/i, "seven"

但是尝试替换 @ 符号不匹配:

str.gsub! /\b@\b/i, "at"

转义似乎也不起作用:

str.gsub! /\b\@\b/i, "at"

最佳答案

这取决于 \b 的解释方式。 \b 是“字边界”,其中如果 \b 前面或后面是单词字符,则发生零长度匹配。单词字符仅限于 [A-Za-z0-9_] 以及其他一些字符,但 @ 不是单词字符,因此 \b 不会在其之前(以及空格之后)匹配。空间本身并不是边界。

More about word boundaries...

如果您需要用周围的空格替换@,您可以在\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来匹配“非单词”字符,与带有“或”管道 |^$ anchor 组合:

# 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+|$) 类似,但可以匹配字符串 $ 的结尾。

关于ruby-on-rails - 为什么正则表达式不能匹配@符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22951220/

相关文章:

java - 检查自定义字符串模式

ruby-on-rails - rails : validating a field is present only if another is present

ruby-on-rails - 如何使用 rspec 测试选择日期?

ruby-on-rails - Cloud9 - rails |将数据库从 SQLite3 更改为 PostgreSQL

ruby - TCPSocket 连接被对端重置

regex - 在进一步匹配之前使用正则表达式收集组

ruby-on-rails - Rails 多对一关联

ruby-on-rails - 为什么 Ruby on Rails 7.x.x 不呈现公共(public)文件夹?不是网站图标或 404.html 页面。我使用我的模块,但它不起作用

ruby - Splat 在论证位置

python - 模糊正则表达式、文本处理、词法分析?