我似乎无法获得与主题标签#
,@
或字边界相匹配的正则表达式。目标是将字符串分解为类似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
后处理的正则表达式?
答案 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"]