簡體   English   中英

使用ruby 2.2根據圖案選擇線

[英]selection of line based on the pattern using ruby 2.2

我有一個名為Regional.txt的文件,其數據如下:

shell.SetMyFile "Ranger" 
shell.SetMyErrorFile "Discovery"
shell.SetMyFileEnabled 1 
shell.SetMyLogFileEnabled 1

現在,我使用ruby讀取此文件,並嘗試以RangerDiscovery的身份過濾“ shell.SetMyFile”“ shell.SetMyErrorFile”中的文本:

File.readlines("regional.txt").each do |line|
      value1 = line.split(" ")[1] if line.include?("shell.SetMyFile")
      value2 = line.split(" ")[1] if line.include?("shell.SetMyErrorFile ")
      puts value1, value2
end

我的結果是1,1,而不是Ranger發現 這是因為包含? 考慮“ shell.SetMyFileEnabled”“ shell.SetMyLogFileEnabled”的方法 如何將其過濾為所需的結果?

快速修復如下:

# Need to declare the variables outside the block,
# so they are not trapped in that scope
value1 = nil
value2 = nil

File.readlines("regional.txt").each do |line|
  # NOTE: added trailing space here:
  if line.include?("shell.SetMyFile ")
    value1 = line.split(" ")[1] 
  end
  if line.include?("shell.SetMyErrorFile ")
    value2 = line.split(" ")[1] 
  end
end

puts value1, value2
# => "Ranger"
# => "Discovery"

您也可以使用正則表達式來做到這一點:

key_vals = File.
  read("regional.txt").
  scan(/\w+\.(\w+)[^\w]+(\w+)/).
  to_h

value1 = key_vals["SetMyFile"]
# => "Ranger"

value2 = key_vals["SetMyErrorFile"]
# => "Discovery"

為了解釋正則表達式,請考慮shell.SetMyFile "Ranger"

  • \\w+ :任意數量的字母數字字符,與前綴匹配,例如shell
  • \\. :文字時期
  • (\\w+) :匹配組1,任意數量的字母數字字符,匹配后綴,例如SetMyFile
  • [^\\w]+任意數量的非字母數字字符,匹配空格以及引號
  • (\\w+)匹配組2,任意數量的字母數字字符。 匹配值字符串,例如Ranger

調用scan您將獲得一個嵌套數組:

File.read("regional.txt").scan(/\w+\.(\w+) \"?(\w+)/)
# => [
#   ["SetMyFile", "Ranger"],
#   ["SetMyErrorFile", "Discovery"], 
#   ["SetMyFileEnabled", "1"],
#   ["SetMyLogFileEnabled", "1"]
# ]

您可以對此調用to_h以將其轉換為哈希,以便通過鍵輕松查找:

讓我們創建您的文件。

FName = "regional.txt"

File.write FName, <<~END
shell.SetMyFile "Ranger" 
shell.SetMyErrorFile "Discovery"
shell.SetMyFileEnabled 1 
shell.SetMyLogFileEnabled 1
END
  #=> 113

我們得到:

desired_lines = ["shell.SetMyFile", "shell.SetMyErrorFile"]

我們了解您希望從文件中打印某些信息。 通常,最好將所需的信息提取到Ruby對象中,然后打印感興趣的信息。 這樣,如果您希望在代碼中操縱結果對象,則不必更改代碼的那部分。

可以將文件的各行讀入一個數組,選擇感興趣的元素,然后提取感興趣的信息。 但是,逐行讀取文件並從那些以desired_lines元素開頭的行中保存感興趣的信息更為有效,該行僅需對文件進行一次遍歷,而無需構造中間數組。 您可以使用IO :: foreachEnumerator#with_object方法來實現

a = IO.foreach(FName).with_object([]) do |line,arr|
  label, value = line.chomp.delete('"').split
  arr << value if desired_lines.include?(label)
end
  #=> ["Ranger", "Discovery"] 

另外,如果您希望將"Ranger""Discovery"綁定到其對應的行,則可以替換為:

arr << [label, value]

對於

arr << value

在這種情況下,返回值為:

[["shell.SetMyFile", "Ranger"], ["shell.SetMyErrorFile", "Discovery"]] 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM