【问题标题】:Why can't regular expressions match for @ sign?为什么正则表达式不能匹配@符号?
【发布时间】:2014-05-21 23:40:30
【问题描述】:

对于字符串Be there @ six.

为什么会这样:

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

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

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

逃避它似乎也不起作用:

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

【问题讨论】:

  • @aliteralmind 那篇文章似乎没有提到“@”。
  • @aliteralmind 我尝试按如下方式转义它,但它似乎仍然无法匹配:/\b\@\b/i
  • 其实是词界问题。不是逃避问题。除非有一个词紧接在它之前结束,或者紧随其后开始,否则它不会匹配。 StackOverflow Regular Expression FAQ:\b:word boundary, and \B:non-word boundary 中的相关问题,列在“锚”类别下,大约下降了 1/4。

标签: ruby-on-rails ruby regex


【解决方案1】:

这取决于\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 空格。

cmets 后更新:

如果您想将@ 视为可能出现在开头或结尾的“单词”,或者在空格内,您可以使用\W 匹配“非单词”字符,并结合@987654342 @带有“或”管道的锚点|

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

【讨论】:

  • 我明白了。有没有办法获得与使用\b 字边界替换@ 相同的结果?
  • 那行不通——因为它也会匹配Be there@six中的@
  • 你可以改用\s+,但它坚持使用空格
  • 我明白了。与\b 提供的结果不太一样,但很接近。
  • 即如果 @ 位于字符串的开头或结尾(或以标点符号结尾),\s+ 仍然会失败。
【解决方案2】:

\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"

【讨论】:

  • Matt 的问题是 'be there@six'.gsub /@/, 'at' 也会匹配。有没有办法获得与使用单词边界相同的结果?
  • @user3188544 最简单的方法可能只是匹配@周围的空白。
  • @user3188544 类似/(?:\A|(?<=\W))@(?:(?=\W)|\z)/ 的东西可能是一种“@ 的单词边界”,但这实际上取决于您要做什么。
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 2020-01-31
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
相关资源
最近更新 更多