【问题标题】:Why is this negative look behind wrong?为什么这种负面的看法是错误的?
【发布时间】:2015-10-19 00:07:19
【问题描述】:
def get_hashtags(post)
    tags = []
    post.scan(/(?<![0-9a-zA-Z])(#+)([a-zA-Z]+)/){|x,y| tags << y}
    tags
end

Test.assert_equals(get_hashtags("two hashs##in middle of word#"), [])
#Expected: [], instead got: ["in"]

不应该向后看,看看匹配不是以单词或数字开头的吗?为什么它仍然接受 'in' 作为有效匹配?

【问题讨论】:

  • 因为模式在第二个 # 上成功(前面没有 [0-9a-zA-Z])。

标签: ruby regex negative-lookbehind


【解决方案1】:

您应该使用\K 而不是消极的后视。这使您可以大大简化您的正则表达式:不需要预定义的数组、捕获组或块。

\K 表示“丢弃到目前为止匹配的所有内容”。这里的关键是可变长度匹配可以在 \K 之前,而(在 Ruby 和大多数其他语言中)可变长度匹配不允许在(负或正)lookbehinds 中。

r = /
    [^0-9a-zA-Z#] # do not match any character in the character class
    \#+           # match one or more pound signs
    \K            # discard everything matched so far
    [a-zA-Z]+     # match one or more letters
    /x            # extended mode

如果我不是在扩展模式下编写正则表达式,请注意 \#+ 中的 # 不需要转义。

"two hashs##in middle of word#".scan r
  #=> []

"two hashs&#in middle of word#".scan r
  #=> ["in"]

"two hashs#in middle of word&#abc of another word.###def ".scan r
   #=> ["abc", "def"] 

【讨论】:

  • 我寻找这个解决方案已经很久了。谢谢,伙计。
猜你喜欢
  • 1970-01-01
  • 2015-12-07
  • 2021-12-08
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2016-10-18
  • 1970-01-01
相关资源
最近更新 更多