正则表达式使用ruby匹配句子中的主题标签

我正在尝试使用ruby on rails为一个简单的大学项目提取主题标签。 我面临的问题是标签只包含数字和没有空格的标签。

text = "Pack my #box with #5 dozen liquor.#jugs link.com/liquor#jugs #2good #first#second" 

我有的正则表达式是/(?:^|\s)#(\w+)/i ( 来源 )

这个正则表达式返回#["box", "5", "2good", "first"]

如何确保它只返回#["box", "2good"]并忽略其余部分,因为它们不是“真正的”主题标签?

你能试试这个正则表达式:

 /(?:^|\s)(?:(?:#\d+?)|(#\w+?))\s/i 

更新1:
在某些情况下,上述正则表达式不匹配:#blah23blah和#23blah23。 因此修改了正则表达式来处理所有情况。

正则表达式:

 /(?:\s|^)(?:#(?!\d+(?:\s|$)))(\w+)(?=\s|$)/i 

分解:

  • (?:\s|^)匹配前面的空格或行的开头。 不捕捉比赛。
  • #匹配哈希但不捕获。
  • (?!\d+(?:\s|$)))否定前瞻以避免#和空格(或行尾)之间的所有数字字符
  • (\w+)匹配并捕获所有单词字符
  • (?=\s|$) – 正面前瞻以确保跟随空格或行尾。 这是确保它匹配相邻的有效哈希标记所必需的。

修改示例文本以捕获大多数情况:

#blah用#5打##good2#3good酒包装我的#box#jugs link.com/liquor#jugs#mkvef214asdwq sd#3e4 flsd#2good#first#second#3

火柴:

比赛1:等等
比赛2:框
比赛3:good2
比赛4:3好
第5场比赛:mkvef214asdwq
比赛6:3e4
比赛7:2好

Rubular链接

更新2:

要排除以下划线开头或结尾的单词,只需在否定前瞻中包含您的排除项,如下所示:

 /(?:\s|^)(?:#(?!(?:\d+|\w+?_|_\w+?)(?:\s|$)))(\w+)(?=\s|$)/i 

样本,正则表达式和匹配项记录在此Rubular链接中

我会这样做:

 text.scan(/ #[[:digit:]]?[[:alpha:]]+ /).map{ |s| s.strip[1..-1] } 

返回:

 [ [0] "box", [1] "2good" ] 

我不会尝试在正则表达式中做所有事情。 我更喜欢让它们尽可能简单,然后在我获得基本数据后过滤和毁坏。 我的理由是正则表达式更难以维持它们变得越复杂。 我宁愿把时间花在维护模式上。

试试这个:

 /\s#([[\d]]?[[az]]+\s)/i 

输出:

 1.9.3-p194 :010 > text = "Pack my #box with #5 dozen liquor.#jugs link.com/liquor#jugs #2good #first#second" => "Pack my #box with #5 dozen liquor.#jugs link.com/liquor#jugs #2good #first#second" 1.9.3-p194 :011 > puts text.scan /\s#([[\d]]?[[az]]+\s)/i box 2good => nil