【问题标题】:Extract first word from a line in a file using Ruby使用 Ruby 从文件中的一行中提取第一个单词
【发布时间】:2015-03-14 16:22:02
【问题描述】:

如何获取每行的第一个单词?感谢 Stack Overflow 上某人的帮助,我正在使用以下代码:

File.open("pastie.rb", "r") do |file|
  while (line = file.gets)
    next if (line[0,1] == " ")
    labwords = line.split.first
    print labwords.join(' ')
  end
end

它从每一行中提取第一个单词,但它存在空格问题。我需要帮助调整它。我需要使用first方法,但是不知道怎么用。

【问题讨论】:

  • 我认为您可能对next if... 行的作用感到困惑。与普通的 if 语句不同,它仅在该行上是完整的,并且以下行不是它的一部分(这是您的缩进所暗示的)。至于您的问题:尝试取出.join(' ') 看看会发生什么。
  • 你是对的。我删除了 .join,因为我遇到了方法错误。

标签: ruby string


【解决方案1】:

如果你想要文件中每一行的第一个单词:

first_words = File.read(file_name).lines.map { |l| l.split(/\s+/).first }

这很简单。让我们把它分开:

File.read(file_name)

读取文件的全部内容并将其作为字符串返回。

.lines

用换行符 (\n) 分割字符串并返回字符串数组。每个字符串代表一个“线”。

.map { |l| ... }

Array#map 调用提供的块,传入每个项目并获取块的返回值来构建一个新数组。一旦Array#map 完成,它就会返回包含新值的数组。这允许您转换值。在此处的示例块中,|l| 是块参数部分,这意味着我们采用一个参数,我们将其引用为 l

|l| l.split(/\s+/).first

这是块内部,为了完整起见,我已经继续并在此处包含了块参数。在这里,我们用/\s+/ 分割线。这是一个正则表达式,\s 表示 任何空格\t \n 和空格),+ 表示 一个或多个,所以 \s+ 表示一个或多个空白字符,当然,它会尝试匹配尽可能多的连续空白字符。将此传递给String#split 将返回一个子字符串数组,这些子字符串出现在给定的分隔符之间。现在,我们的分隔符是一个或多个空格,所以我们应该得到空格之间的所有内容。如果我们有字符串"A list of words",我们将在拆分调用后得到["A", "list", "of", "words"]。它非常有用。最后,我们调用.first,它返回数组的第一个元素(在本例中为“第一个单词”)。

现在,在 Ruby 中,块中最后一个表达式的计算值会自动返回,所以我们的第一个单词会被返回,并且假设这个块被传递给 map,我们应该从文件中获取第一个单词的数组。为了演示,让我们输入(假设我们的文件包含):

This is line one
And line two here
Don't forget about line three
Line four is very board
Line five is the best
It all ends with line six

通过上面的行运行我们得到:

["This", "And", "Don't", "Line", "Line", "It"]

每行的第一个单词。

【讨论】:

  • 这非常有用。谢谢你。 .map 对我来说仍然有点混乱。我会研究你写的东西并做更多的研究。
  • Map 非常简单:它只是通过一个子例程运行数组的每个元素并返回一个包含这些值的新数组。例如,假设您想将数组中的每个值都乘以 2。您可以使用地图:array_by_two = [1,2,3,4].map{|val| val * 2 }array_by_two == [2,4,6,8]
【解决方案2】:

考虑一下:

def first_words_from_file(file_name)
  lines = File.readlines(file_name).reject(&:empty?)
  lines.map do |line|
    line.split.first
  end
end

puts first_words_from_file('pastie.rb')

【讨论】:

  • lines = File.open(file_name, 'r') { |f| f.readlines } 是一种将文件读入数组的非常尴尬的方式。请改用File.readlines(file_name)。它做同样的事情。不要在map 中使用next if line.empty?,因为这会迫使您事后使用compact。相反,在使用 map 之前使用 selectreject 过滤掉空行。
  • 谢谢,我希望接下来避免收集nil。但是我添加了那个紧凑型以将其取出。题外话:不应该有办法跳过值吗?
猜你喜欢
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多