【问题标题】:How can I print a string and pause when there's a full stop or "..." in Ruby?当Ruby中有句号或“...”时,如何打印字符串并暂停?
【发布时间】:2021-03-09 20:03:58
【问题描述】:

我正在尝试用 Ruby 编写一个程序,该程序打印文本并在每个句号“。”时都暂停。或字符串中的“...”。到目前为止,我已经有了这个,但不知道下一步该去哪里。

def talk(text, speed = 0.008)
    pause = speed * 100
    text.each_char do |char| 
        print char
        if char == '.'
            sleep(pause)
        end
        sleep(speed) 
    end
    return
end

# e.g. talk("I can see something... It's getting closer... Oh no.")

它暂停一个句号很好,但显然不能连续三个,因为它只是重复暂停三次。我更像是一个初学者,正在努力寻找解决方案。感谢阅读

【问题讨论】:

    标签: ruby iteration pause


    【解决方案1】:

    这是我的建议——打印所有出现的.s,在打印下一个字符之前休眠。

    def talk(text, speed = 0.008)
        pause = speed * 100
        last_char = nil # keep track of the previous character.
    
        text.each_char do |char|
            if char == '.' 
                # no sleep at all for periods
                print('.')
            else
                # we're going to print something, if the last character was a period,
                # pause before doing it.  
                sleep(pause) if last_char == '.'
                print char
                # finally, a regular sleep 
                sleep(speed)
            end
            # and update the last character we saw
            last_char = char
        end
    end
    

    当然,有很多不同的方法可以解决这个问题!

    【讨论】:

      【解决方案2】:
      def talk(text, speed = 0.008)
        pause = speed * 100
        r = /(\.{3}|\.)/
        text.split(r).each do |str|
          if str.match?(r)
            sleep(pause)
          else
            print str
          end
        end
        puts
      end
      
      talk("Mary had .a lit...tle .lamb", 0.04)
        #=> Mary had a little lamb
                    ^     ^      ^
      

      每一个由派对帽表示的字符被打印出来后,都会出现四秒的延迟。

      步骤如下。

      text = "Mary had .a lit...tle .lamb"
      speed = 0.04
      pause = speed * 100
      r = /(\.{3}|\.)/
      

      这个正则表达式读作“匹配捕获组 1 中的三个句点或 (|) 一个句点”(由括号定义的捕获组)。这与 /(\.|\.{3})/ 不同,后者将匹配每组三个单独的每个周期(即| 之前的\. 将在每个周期成功,无论是否属于一个组)。

      a = text.split((r))
        #=> ["Mary had ", ".", "a lit", "...", "tle ", ".", "lamb"]
      

      请参阅String#split,它解释了捕获组需要在返回的数组中包含拆分字符串。

      继续,

      a.each do |str|
        if str.match?(r)
          sleep(pause)
        else
          print str
        end
      end
      

      这将打印(不带换行符)"Mary had ",休眠四秒钟,打印"a lit",再休眠四秒钟,等等。

      puts
      

      需要最后一条语句来打印换行符以终止该行。


      另一种方法是对问题中给出的方法进行一些小改动。

      def talk(text, speed = 0.008)
        pause = speed * 100
        text.squeeze('.').each_char do |char| 
          if char == '.'
            sleep(pause)
          else
            print char
          end
        end
        puts
      end
      

      请参阅String#squeeze,它将两个或多个句点的每个字符串转换为一个句点。

      这种方法与之前的方法不同之处在于它对连续两个或三个以上的句号进行处理。

      【讨论】:

        猜你喜欢
        • 2013-07-23
        • 1970-01-01
        • 2019-02-07
        • 1970-01-01
        • 2013-06-14
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 2012-04-22
        相关资源
        最近更新 更多