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

时间:2012-08-24 03:22:59

标签: ruby regex twitter hashtag

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

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

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

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

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

3 个答案:

答案 0 :(得分:10)

你能试试这个正则表达式吗?

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

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

正则表达式:

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

细分:

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

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

  #b> #blah用#5打#ack2#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 link

更新2:

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

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

示例,正则表达式和匹配项记录在此Rubular link

答案 1 :(得分:2)

我会这样做:

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

返回:

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

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

答案 2 :(得分:1)

试试这个:

/\s#([[\d]]?[[a-z]]+\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]]?[[a-z]]+\s)/i 
box 
2good 
 => nil