Mat*_*ner 59 python parsing split scanf procfs
我正在寻找与sscanf()Python 相当的东西.我想解析/proc/net/*文件,在CI中可以做这样的事情:
int matches = sscanf(
buffer,
"%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
local_addr, &local_port, rem_addr, &rem_port, &inode);
Run Code Online (Sandbox Code Playgroud)
我首先想到的是str.split,但是它不会拆分给定的字符,而是整个sep字符串:
>>> lines = open("/proc/net/dev").readlines()
>>> for l in lines[2:]:
>>> cols = l.split(string.whitespace + ":")
>>> print len(cols)
1
Run Code Online (Sandbox Code Playgroud)
如上所述,应该返回17.
是否有一个等价于sscanf(不是RE)的Python ,或者标准库中的字符串拆分函数,它分裂了我不知道的任何一系列字符?
Cra*_*een 65
还有parse模块.
parse()被设计为与format()(Python 2.6及更高版本中较新的字符串格式化函数)相反.
>>> from parse import parse
>>> parse('{} fish', '1')
>>> parse('{} fish', '1 fish')
<Result ('1',) {}>
>>> parse('{} fish', '2 fish')
<Result ('2',) {}>
>>> parse('{} fish', 'red fish')
<Result ('red',) {}>
>>> parse('{} fish', 'blue fish')
<Result ('blue',) {}>
Run Code Online (Sandbox Code Playgroud)
Chr*_*lin 59
当我处于C语言中时,我通常使用zip和列表推理来实现类似scanf的行为.像这样:
input = '1 3.0 false hello'
(a, b, c, d) = [t(s) for t,s in zip((int,float,strtobool,str),input.split())]
print (a, b, c, d)
Run Code Online (Sandbox Code Playgroud)
请注意,对于更复杂的格式字符串,您需要使用正则表达式:
import re
input = '1:3.0 false,hello'
(a, b, c, d) = [t(s) for t,s in zip((int,float,strtobool,str),re.search('^(\d+):([\d.]+) (\w+),(\w+)$',input).groups())]
print (a, b, c, d)
Run Code Online (Sandbox Code Playgroud)
另请注意,您需要转换所有要转换的类型的转换函数.例如,上面我使用了类似的东西:
strtobool = lambda s: {'true': True, 'false': False}[s]
Run Code Online (Sandbox Code Playgroud)
Mik*_*ham 29
Python没有sscanf等效的内置函数,并且大多数情况下,通过直接使用字符串,使用正则表达式或使用解析工具来解析输入实际上更有意义.
可能对翻译C大多有用,人们已经实现了sscanf,例如在这个模块中:http://hkn.eecs.berkeley.edu/~dyoo/python/scanf/
在这种特殊情况下,如果您只想基于多个拆分字符拆分数据,那么re.split它确实是正确的工具.
Die*_*Epp 23
您可以使用该re模块拆分一系列字符.
>>> import re
>>> r = re.compile('[ \t\n\r:]+')
>>> r.split("abc:def ghi")
['abc', 'def', 'ghi']
Run Code Online (Sandbox Code Playgroud)
ori*_*rip 14
您可以re使用命名组解析模块.它不会将子字符串解析为它们的实际数据类型(例如int),但在解析字符串时非常方便.
鉴于此示例行来自/proc/net/tcp:
line=" 0: 00000000:0203 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 335 1 c1674320 300 0 0 0"
Run Code Online (Sandbox Code Playgroud)
使用变量模仿sscanf示例的示例可能是:
import re
hex_digit_pattern = r"[\dA-Fa-f]"
pat = r"\d+: " + \
r"(?P<local_addr>HEX+):(?P<local_port>HEX+) " + \
r"(?P<rem_addr>HEX+):(?P<rem_port>HEX+) " + \
r"HEX+ HEX+:HEX+ HEX+:HEX+ HEX+ +\d+ +\d+ " + \
r"(?P<inode>\d+)"
pat = pat.replace("HEX", hex_digit_pattern)
values = re.search(pat, line).groupdict()
import pprint; pprint values
# prints:
# {'inode': '335',
# 'local_addr': '00000000',
# 'local_port': '0203',
# 'rem_addr': '00000000',
# 'rem_port': '0000'}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
106772 次 |
| 最近记录: |