【问题标题】:Extracting (and modifying) all words from text that begin with a specific string?从以特定字符串开头的文本中提取(和修改)所有单词?
【发布时间】:2014-02-20 19:44:38
【问题描述】:

我正在寻找一种更有效的方法来从以特定字符串开头的文本块中选择单词。如果可能的话,我还想同时修改它们。就我而言,我正在寻找主题标签并将它们小写,所以给定一个字符串:

the quick brown #Fox jumps over the lazy #dog

我想生成数组:

["#fox","#dog"]

甚至:

["fox","dog"]

目前我的(可能是低效的)代码如下所示:

words = item.body.split(" ")
tagged_words = words.select{|x| x[0,1] == "#"}
tagged_words = tagged_words.map{ |x| x.downcase }

我假设前两行可以用正则表达式替换,但无法弄清楚。也许甚至有一种方法可以组合所有三行代码?

这部分可能与大众不太相关,但我最终想要做的是获取完整的标签列表并将其减少为仅在项目正文中未引用的标签。这需要多行代码,因此非常感谢任何可以重写整个过程以提高效率的人。

external_tags = item.tags.select{|tag| !tagged_words.include?("#"+tag.name)}

我搜索了一段时间以寻找问题第一部分的答案,但找不到。任何引用我的更一般问题的答案的回复/评论当然就足够了。

【问题讨论】:

    标签: ruby regex arrays


    【解决方案1】:
    s = "the quick brown #Fox jumps over the lazy #dog"
    p s.scan(/(^|\s)#(\S+)/).map { |m| m[1].downcase }
    # => ["fox", "dog"]
    

    如果我错了,请纠正我,但是一旦这部分工作正常,您似乎已经回答了问题的第二部分。

    【讨论】:

      【解决方案2】:

      只抓取标签:

      'the quick brown #Fox jumps over the lazy #dog'.scan(/#\S+/)
      # => ["#Fox", "#dog"]
      

      如果你不想要井号:

      'the quick brown #Fox jumps over the lazy #dog'.scan(/(?<=#)\S+/)
      # => ["Fox", "dog"]
      

      使用后视匹配但不捕获“#”字符。

      或者:

      'the quick brown #Fox jumps over the lazy #dog'.scan(/#\S+/).map{ |s| s.tr('#', '') }
      # => ["Fox", "dog"]
      

      或者:

      'the quick brown #Fox jumps over the lazy #dog'.scan(/#\S+/).map{ |s| s.delete('#') }
      # => ["Fox", "dog"]
      

      或者:

      'the quick brown #Fox jumps over the lazy #dog'.scan(/#\S+/).map{ |s| s.sub('#', '') }
      # => ["Fox", "dog"]
      

      【讨论】:

        【解决方案3】:
        tag_string = "the quick brown #Fox jumps over the lazy #dog"
        tag_string.split(" ").select{|a| /^#/.match(a)}.map(&:downcase)
        

        【讨论】:

          【解决方案4】:

          这都是关于单词字符和单词边界的:

          "the quick brown #Fox jumps over the lazy #dog".scan /\B#\w+\b/
          #=> ["#Fox", "#dog"]
          

          帮自己一个忙,learn all about them

          【讨论】:

            【解决方案5】:

            这个怎么样? (Positive lookbehind)

            str = "the quick brown #Fox jumps over the lazy #dog"
            str.scan(/#\w+/)
            => ["#Fox", "#dog"]
            
            # using Positive lookbehind 
            str.scan(/(?<=#)\w+/)
            => ["Fox", "dog"]
            
            str.scan(/(?<=#)\w+/).map(&:downcase)
            => ["fox", "dog"]
            

            【讨论】:

            • 不要在scan 模式中使用捕获,你将不会得到数组的数组,这将避免flatten 输出。
            • @theTinMan 感谢您的建议!现在看起来好多了:-)
            猜你喜欢
            • 1970-01-01
            • 2015-04-28
            • 2013-08-29
            • 1970-01-01
            • 2018-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-06
            相关资源
            最近更新 更多