我想解析uptime
Unix命令的输出。
这是两个不同的样本:
14:25 up 1 day, 1:24, 2 users, load averages: 0,56 0,48 0,47
14:25 up 1:24, 2 users, load averages: 0,56 0,48 0,47
(我使用的语言是Python)
因此,请将上面的两个示例保存到变量s1
和s2
中。
这是我写的代码:
>>> RE = r'''
((\d) \s day)? # this should match "n day" if it's there
.*? # this should match everything until the next regex
\s(\d{1,2}):(\d{1,2}) # this should match a space followed by "hh:mm"
'''
>>> print re.match(RE, s1, re.VERBOSE).groups()
(None, None, '1', '24')
>>> print re.match(RE, s2, re.VERBOSE).groups()
(None, None, '1', '24')
正则表达式的第二部分,即抓住正常运行时间的小时数,可以完美运行。但为什么元组的第一部分总是None
?我错过了什么?这是贪心 vs 非贪婪问题吗?
答案 0 :(得分:3)
您希望将.*?
移至可选日期组并使用.search()
:
RE = r'''
(?:(\d) \s day.*?)? # this should match "n day" if it's there
\s(\d{1,2}):(\d{1,2}) # this should match a space followed by "hh:mm"
'''
演示:
>>> RE = r'''
... (?:(\d) \s day.*?)? # this should match "n day" if it's there
... \s(\d{1,2}):(\d{1,2}) # this should match a space followed by "hh:mm"
... '''
>>> print re.search(RE, s1, re.VERBOSE).groups()
('1', '1', '24')
>>> print re.search(RE, s2, re.VERBOSE).groups()
(None, '1', '24')
模式锚定在:
上,然后回溯。然后.*?
匹配时间签名之前的整个文本,这满足模式。
将.*?
部分移动到可选的day
组(在我的版本中未捕获),您可以保证它不会超越{{1文字文字。
答案 1 :(得分:0)
匹配从字符串的开头开始,添加。*?在开头
In [37]: RE=r'.*?((\d) \s day) .*? \s(\d{1,2}):(\d{1,2})'
In [38]: print re.match(RE, s1, re.VERBOSE).groups()
('1 day', '1', '1', '24')
答案 2 :(得分:0)
而不是从命令行读取,另一种方法是直接从/proc/uptime
#!/usr/bin/python
from datetime import timedelta
with open('/proc/uptime', 'r') as f:
uptime_seconds = float(f.readline().split()[0])
uptime_string = str(timedelta(seconds = uptime_seconds))
print(uptime_string)
输出:
35 days, 23:06:35.530000
现在使用tokenise或拆分内置函数更容易解析