用于从 Open3.popen3 标准输出中提取值的正则表达式

标签 regex ruby regex-group

如何获取外部命令的输出并从中提取值?

我有这样的东西:

stdin, stdout, stderr, wait_thr = Open3.popen3("#{path}/foobar", configfile)

if /exit 0/ =~ wait_thr.value.to_s
    runlog.puts("Foobar exited normally.\n")
    puts "Test completed."
    someoutputvalue = stdout.read("TX.*\s+(\d+)\s+")
    puts "Output value: " + someoutputvalue
end

我没有在标准输出上使用正确的方法,因为 Ruby 告诉我它不能将字符串转换为整数。

例如,如果输出是

"TX So and so:     28"

我只想得到“28”。我验证了上面的正则表达式匹配我需要匹配的内容,我只是想知道如何将提取的值存储在变量中。

这样做的正确方法是什么?我在文档中的任何地方都找不到可用于 stdout 的方法。我正在使用来自 Ruby 1.9.3 的 stout.read

最佳答案

所有需要的信息都在 Popen3 documentation 中,但您必须通读所有内容并非常仔细地查看示例。您还可以从 Process docs 中收集有用的信息。也是。

也许这会更好地解释它:

require 'open3'

captured_stdout = ''
captured_stderr = ''
exit_status = Open3.popen3(ENV, 'date') {|stdin, stdout, stderr, wait_thr|
  pid = wait_thr.pid # pid of the started process.
  stdin.close
  captured_stdout = stdout.read
  captured_stderr = stderr.read
  wait_thr.value # Process::Status object returned.
}

puts "STDOUT: " + captured_stdout
puts "STDERR: " + captured_stderr
puts "EXIT STATUS: " + (exit_status.success? ? 'succeeded' : 'failed')

运行输出:

STDOUT: Wed Jun 12 07:07:12 MST 2013
STDERR:
EXIT STATUS: succeeded

注意事项:

  • 你经常需要close stdin溪流。如果被调用的应用程序需要 STDIN 上的输入,它将挂起,直到它看到流关闭,然后将继续其处理。
  • stdin , stdout , stderr是 IO 句柄,所以你必须阅读 IO class documentation找出可用的方法。
  • 你必须输出到stdin使用 puts , printwrite , 和 readgets来自 stdoutstderr .
  • exit_status不是字符串,它是 Process::Status 类的一个实例。你可能会尝试从它的 to_s 中解析版本,但不要。而是使用访问器来查看返回的内容。
  • 我通过了 ENV哈希,因此子程序可以访问父程序看到的整个环境。没有必要这样做;相反,如果您不想让 child 访问所有内容,您可以为 child 创建一个简化的环境,或者您可以通过改变值(value)观来扰乱他对环境的看法。
  • 代码stdout.read("TX.*\s+(\d+)\s+")发贴的问题是,嗯...废话。我不知道你从哪里得到的,因为在 Ruby 的 IO 类中没有记录 IO#readIO.read .

使用更方便 capture3如果您不需要写入被调用代码的 STDIN:

require 'open3'

stdout, stderr, exit_status = Open3.capture3('date')

puts "STDOUT: " + stdout
puts "STDERR: " + stderr
puts "EXIT STATUS: " + (exit_status.success? ? 'succeeded' : 'failed')

哪些输出:

STDOUT: Wed Jun 12 07:23:23 MST 2013
STDERR:
EXIT STATUS: succeeded

使用正则表达式从字符串中提取值是微不足道的,并且在 Regexp documentation 中很好地涵盖了.从上一个代码示例开始:

stdout[/^\w+ (\w+ \d+) .+ (\d+)$/]
puts "Today is: " + [$1, $2].join(' ')

哪些输出:

Today is: Jun 12 2013

那是使用 String.[] 非常灵活的方法。

另一种方法是使用“命名捕获”:

/^\w+ (?<mon_day>\w+ \d+) .+ (?<year>\d+)$/ =~ stdout
puts "Today is: #{ mon_day } #{ year }"

输出相同的东西。命名捕获的缺点是它们速度较慢,我认为这有点方便。


"TX So and so: 28"[/\d+$/]
=> "28"

关于用于从 Open3.popen3 标准输出中提取值的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17067010/

相关文章:

javascript - 在正则表达式中转义变量

ruby-on-rails - 仅从 IMAP 服务器获取新邮件

ruby-on-rails - 在 Rails 控制台和 Controller 中需要一个 Ruby 模块

c# - .NET 中具有重复字符和长度的正则表达式

regex - 剪切和粘贴正则表达式时,emacs 自动转义 '\'

regex - 查找/替换正则表达式以删除 html 标签

ruby - 一个哈希中的多个子哈希

regex - BASH 正则表达式匹配 MAC 地址

python - 正则表达式重叠包含

java - 在JAVA中使用这个正则表达式有什么问题?