8

我正在尝试使用 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"]并忽略其余部分,因为它们不是“真正的”主题标签?

4

3 回答 3

10

你可以试试这个正则表达式:

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

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

正则表达式:

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

分解:

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

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

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

火柴:

第 1 场:blah
第 2 场:框
第 3 场:good2
第 4 场:3good 第
5 场:mkvef214asdwq
第 6 场:3e4
第 7 场:2good

红色链接

更新 2:

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

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

示例、正则表达式和匹配项记录在此Rubular 链接中

于 2012-08-24T03:55:04.097 回答
2

我会这样做:

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

返回:

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

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

于 2012-08-24T03:41:22.843 回答
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
于 2012-08-24T11:35:32.193 回答