sscanf в Python

Я ищу эквивалент 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 (не РЕ), или строковое разделение функционируют в стандартной библиотеке, которая разделяет на каком-либо диапазоне символов, о которых я не знаю?

59
задан Andrew Grimm 6 October 2011 в 22:51
поделиться

6 ответов

Python не имеет встроенного эквивалента sscanf , и в большинстве случаев имеет смысл анализируйте ввод, работая со строкой напрямую, используя регулярные выражения или используя инструмент синтаксического анализа.

Вероятно, наиболее полезно для перевода C, люди реализовали sscanf , например, в этом модуле: http://hkn.eecs.berkeley.edu/~dyoo/python/scanf/

В этом конкретном случае, если вы просто хотите разделить данные на основе нескольких разделенных символов, re.split действительно правильный инструмент.

29
ответ дан 24 November 2019 в 18:01
поделиться

Вы можете разделить диапазон символов с помощью модуля re.

>>> import re
>>> r = re.compile('[ \t\n\r:]+')
>>> r.split("abc:def  ghi")
['abc', 'def', 'ghi']
23
ответ дан 24 November 2019 в 18:01
поделиться

Вы можете выполнить синтаксический анализ с помощью модуля 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'}
14
ответ дан 24 November 2019 в 18:01
поделиться

Если разделителями являются ':', то можно разделить на ':', а затем использовать x.strip() на строках, чтобы избавиться от лидирующих или скользящих пробельных символов. int() будет игнорировать пробелы.

0
ответ дан 24 November 2019 в 18:01
поделиться

вы можете повернуть ":" в пробел и сделать split.eg

>>> f=open("/proc/net/dev")
>>> for line in f:
...     line=line.replace(":"," ").split()
...     print len(line)

без регекса (в данном случае)

.
1
ответ дан 24 November 2019 в 18:01
поделиться

Проголосовали за ответ orip. Я думаю, что это разумный совет использовать re module. Приложение Kodos полезно при приближении к сложной задаче регулярного выражения с помощью Python.

http://kodos.sourceforge.net/home.html

1
ответ дан 24 November 2019 в 18:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: