0

我还是 Python 的新手,我一直在使用一个脚本来从我的 Raspberry Pi 获取系统信息,比如 cpu temp 等,并将其导入到谷歌文档电子表格中。我的目标是从输出中提取数字,格式为temp=54.1'C. 我需要单独的数字才能随着时间的推移绘制数据......

我在用着:

import gdata.spreadsheet.service
import os
import subprocess
import re

email = 'myemail@gmail.com'
password = 'mypassword'

spreadsheet_key = 'sjdaf;ljaslfjasljdgasjdflasdjfgkjvja'
worksheet_id = '1'

def temp():
   command = "/opt/vc/bin/vcgencmd measure_temp"
   proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
   output = proc.stdout.read()
   return output

def main():
   spr_client = gdata.spreadsheet.service.SpreadsheetsService()
   spr_client.email = email
   spr_client.password = password
   spr_client.ProgrammaticLogin()

   dict = {}
   dict['temp'] = temp()

   entry = spr_client.InsertRow(dict, spreadsheet_key, worksheet_id)

if __name__ == '__main__':
      try:
         main()
      except:
         print "Insert Row Failed!"

以上给出了标准结果。我尝试修改 re.findall(),但无法获得正确的位置或条件的正确组合(r、'/d+'、s 和其他东西)以使其仅返回数字 54.1.. .我基本上以“插入行失败”告终

任何指导将不胜感激。谢谢!

4

2 回答 2

0

You were on the right track using re; your best bet (assuming the decimal can be arbitrary, etc.) is something like this:

import re

def temp():
    command = "/opt/vc/bin/vcgencmd measure_temp"
    proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    output = proc.stdout.read()

    # Build the regex. Use () to capture the group; we want any number of
    # digits \d or decimal points \. that is preceded by temp= and
    # followed by 'C
    temp_regex = re.compile(r'temp=([\d\.]*)\'C')
    matches = re.findall(temp_regex, output)   # now matches = ['54.1']

    temp = float(matches[0])
    return temp

The regex captures any combination of numbers and decimal places (e.g. 12.34.56 would get matched); you could restrict it if necessary to only allow a single decimal place, but that's more work than it appears to be worth, if you can trust that the data you're getting back is well-formed. If you do want the number to be more precise, you could compile the regex like this (for at least one numeral preceding the decimal place and exactly one following it):

temp_regex = re.compile(r'temp=(\d+.\d)\'C')

Again, we capture the expression using the parentheses (captured groups are returned by findall), but this time, increase the specificity of what we're looking for. This will capture any number like 123.4 but not .4 and not 123. If you find that you need to broaden it out a bit but still want only one decimal place:

temp_regex = re.compile(r'temp=(\d+.\d+)\'C')

That will capture any number with at least one numeral proceeding and following the decimal, so 1234.5678 would match but 1234. would not and .1234 would not.

As an alternative to using re.findall(), you might use re.match(), which returns match objects. Then your usage would look something like this (using the direct method, rather than pre-compiling the string:

match = re.match(r'temp=(\d+.\d+)\'C', output)
if match:
    temp = float(match.group(1))   # get the first matching group captured by ()
else:
    pass   # You should add some error handling here

One of the things this makes clearer than the way I had re.findall() above is that if nothing is captured, you have an issue, and you need to figure out how to handle it.


You can look at other ways to vary that up at Regular-Expressions.info, easily the best site I've found on the web for a quick resource on the topic.

于 2013-05-14T03:30:37.433 回答
0

好吧,我已经花了太多时间搞砸了。我似乎无法得到output = proc.stdout.read()给我任何东西。我尝试了几十种组合re但没有运气。

然后我开始研究 replace() 方法。这可能不是最巧妙的方法,但我知道输出将始终采用“temp=XX.X'C”的形式(X 是数字),所以我最终这样做了:

def temp():
   command = "/opt/vc/bin/vcgencmd measure_temp"
   proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
   output = proc.stdout.read()
   output1 = output.replace("temp=","")
   output2 = output1.replace("'C","")
   return output2

它奏效了!它在 Google 电子表格中显示为我需要的数字。

无论如何,感谢您对此的帮助,我会继续尝试re在其他应用程序中实现,也许我会找出为什么我无法让它与它一起工作。

于 2013-05-15T03:00:05.383 回答