与Ruby中的数组元素交互

时间:2014-12-12 08:55:47

标签: ruby arrays regex

我正在尝试用我的代码做一些事情,我对如何与数组的元素进行交互感到困惑。这段代码的要点是将一个字符串作为输入并编辑某些单词。

我的目标是:

  1. 让我的程序编辑多个单词。

  2. 创建一个新的编辑字符串并将其另存为变量,而不是仅将其打印到控制台

  3. 我用评论概述了我的逻辑(评论中也有几个问题)。

    puts "Write something: "
    
    text = gets.chomp
    
    puts "Redact some words: "
    
    redact = gets.chomp
    
    words = text.split(" ")  #Turns string into array of words
    
    redact_words = text.split(" ")
    
    words.each do |word|        #Iterates through each component of array [words] and permanently  
    word.downcase!              #makes the placeholder (word) lower case.
     end                        #Apparently this works also: words.map!(&:downcase) to make it
                                  #undercase but I'm not sure why? What is .map? What is &:?
    
    words.each do |word|
    
    if redact_words.include?(word)   #iterates through each component of array [redact_words] and 
                                     #checks if it includes the placeholder (word). If it does,
    text.gsub!("#{word}","REDACTED") # it permanently globally substitutes the string of placeholder
                                     #(word) with the string "REDACTED".
    else puts "No redactable word(s) found"
    end
    end
    puts text
    

    我的代码效果不好,但因为它没有看到大写。

    如果您输入“Hello hello Okay okay”作为第一个输入。并且“你好没问题”作为第二个输入。你得到“Hello CONTACTED Okay REDACTED as the output。

    认为它是因为它打印修改后的字符串文本而不是数组[words](这是我想要的,因为我希望将编辑后的字符串保存到变量中)。还有另一种方法吗?

    另外,除了使用regexp(正则表达式)之外,有没有办法进行替换?

2 个答案:

答案 0 :(得分:1)

回答有关words.map!(&:downcase)工作原因的问题:

  1. each类似,map遍历数组中的每个项目,并将该项目传递给给定的块。不同之处在于它使用返回的项创建一个新数组。 map!用返回的项替换当前数组中的项,而不是创建新数组。 reference
  2. &:downcase{|x| x.downcase }的快捷方式。它实质上是对数组中的每个项调用指定的方法,并使用返回的值作为新值。
  3. 以下是使用正则表达式的脚本版本:

    puts "Write something: "
    
    text = gets.chomp
    
    puts "Redact some words: "
    
    redact = gets.chomp
    
    redact_words = redact.split(" ")
    
    # The %r syntax creates a regular expression using interpolation, the /i means to ignore case
    new_text = text.gsub(%r/\b(#{redact_words.join('|')})\b/i, 'REDACTED')
    
    puts "No redactable word(s) found" if new_text == text
    
    puts new_text
    

答案 1 :(得分:0)

您应该使搜索不区分大小写。

最简单的方法是构建一个正则表达式(使用Regexp.union),然后将其与整个字符串匹配:

def redact(text, redact)
  redact_words = redact.split(" ")  
  redact_patterns = redact_words.map { |word| /\b#{word}\b/i } # /i makes it case insensitive, 
                                                               # \b makes it whole word only
  text.gsub(Regexp.union(redact_patterns), 'REDACTED')
end

redact('Hello hello Okay okay', "hello okay")
# => "REDACTED REDACTED REDACTED REDACTED"