Я ищу эквивалент sscanf()
в Python. Я хочу проанализировать /proc/net/*
файлы, в C я мог сделать что-то вроде этого:
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);
Я думал сначала для использования str.split
, однако это не разделяет на данных символах, но sep
строка в целом:
>>> lines = open("/proc/net/dev").readlines()
>>> for l in lines[2:]:
>>> cols = l.split(string.whitespace + ":")
>>> print len(cols)
1
Который должен возвращаться 17, как объяснено выше.
Есть ли Python, эквивалентный sscanf
(не РЕ), или строковое разделение функционируют в стандартной библиотеке, которая разделяет на каком-либо диапазоне символов, о которых я не знаю?
Python не имеет встроенного эквивалента sscanf
, и в большинстве случаев имеет смысл анализируйте ввод, работая со строкой напрямую, используя регулярные выражения или используя инструмент синтаксического анализа.
Вероятно, наиболее полезно для перевода C, люди реализовали sscanf
, например, в этом модуле: http://hkn.eecs.berkeley.edu/~dyoo/python/scanf/
В этом конкретном случае, если вы просто хотите разделить данные на основе нескольких разделенных символов, re.split
действительно правильный инструмент.
Вы можете разделить диапазон символов с помощью модуля re
.
>>> import re
>>> r = re.compile('[ \t\n\r:]+')
>>> r.split("abc:def ghi")
['abc', 'def', 'ghi']
Вы можете выполнить синтаксический анализ с помощью модуля 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"
Пример, имитирующий ваш пример 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'}
Если разделителями являются ':', то можно разделить на ':', а затем использовать x.strip() на строках, чтобы избавиться от лидирующих или скользящих пробельных символов. int() будет игнорировать пробелы.
вы можете повернуть ":" в пробел и сделать split.eg
>>> f=open("/proc/net/dev")
>>> for line in f:
... line=line.replace(":"," ").split()
... print len(line)
без регекса (в данном случае)
.Проголосовали за ответ orip. Я думаю, что это разумный совет использовать re module. Приложение Kodos полезно при приближении к сложной задаче регулярного выражения с помощью Python.