如何匹配Word Boundary"或" [@#]?

时间:2014-03-25 13:13:15

标签: ruby regex word-boundary

我似乎无法获得与主题标签#@或字边界相匹配的正则表达式。目标是将字符串分解为类似Twitter的实体和主题:

input = "Hello @world, #ruby anotherString" 
input.scan(entitiesRegex) 
# => ["Hello", "@world", "#ruby", "anotherString"]

为了得到单词"anotherString",这个单词太大了,很简单:

/\b\w{3,12}\b/

将返回["Hello", "world", "ruby"]。不幸的是,这并不包括主题标签和@。它似乎应该只用于:

/[\b@#]\w{3,12}\b/

但返回["@world", "#ruby"]。这让我意识到单词边界根本不是一个字符,所以它们不属于"单个字符"因此,不会匹配。还有一些尝试:

/\b|[@#]\w{3,12}\b/

返回["", "", "@world", "", "#ruby", "", "", ""]

/((\b|[@#])\w{3,12}\b)/

匹配正确的东西,但按预期返回[[""], ["@"], ["#"], [""]],因为大括号也意味着捕获所有内容。

/((\b|[@#])\w{3,12}\b)/

有点作品。它返回[["Hello", ""], ["@world", "@"], ["#ruby", "#"]]。所以现在所有正确的项目都在那里,它们只是位于每个子阵列的第一个元素。以下代码段在技术上有效:

input.scan(/((\b|[@#])\w{3,12}\b)/).collect(&:first)

是否可以简化此操作以匹配并返回正确的子字符串,只需使用不需要collect后处理的正则表达式?

1 个答案:

答案 0 :(得分:4)

您可以使用正则表达式/[@#]?\b\w+\b/。也就是说,可选地匹配@#,后跟一个字边界(在#ruby中,该边界位于#ruby之间,正常的单词,它也会在单词的开头匹配)和一堆单词字符。

p "Hello @world, #ruby anotherString".scan(/[@#]?\b\w+\b/)
# => ["Hello", "@world", "#ruby", "anotherString"]

此外,您可以使用量词调整匹配单词应具有的字符数。您在对已删除答案的评论中举例说明,仅使用#ruby{3,4}匹配:

p "Hello @world, #ruby anotherString".scan(/[@#]?\b\w{3,4}\b/)
# => ["#ruby"]