파이썬의 sscanf
sscanf()
파이썬에서 와 동등한 것을 찾고 있습니다. /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);
처음에는을 사용하려고 생각 str.split
했지만 주어진 문자로 분할되지 않고 sep
전체 문자열로 나뉩니다 .
>>> lines = open("/proc/net/dev").readlines()
>>> for l in lines[2:]:
>>> cols = l.split(string.whitespace + ":")
>>> print len(cols)
1
위에서 설명한대로 17을 반환해야합니다.
sscanf
(RE가 아님)에 해당하는 Python 또는 내가 알지 못하는 문자 범위를 분할하는 표준 라이브러리의 문자열 분할 함수가 있습니까?
파이썬에는 sscanf
동등한 내장 기능 이 없으며 , 대부분의 경우 실제로 문자열로 직접 작업하거나 정규 표현식을 사용하거나 구문 분석 도구를 사용하여 입력을 구문 분석하는 것이 훨씬 더 합리적입니다.
아마도 C 번역에 대부분 유용 할 것입니다. 사람들은 다음 sscanf
과 같은 모듈을 구현했습니다 . http://hkn.eecs.berkeley.edu/~dyoo/python/scanf/
이 특별한 경우 여러 분할 문자를 기반으로 데이터를 분할하려는 경우 re.split
실제로 올바른 도구입니다.
도 있습니다 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',) {}>
내가 C 분위기 일 때, 나는 보통 scanf와 같은 행동을 위해 zip과 list comprehensions를 사용합니다. 이렇게 :
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)
더 복잡한 형식 문자열의 경우 정규 표현식을 사용해야합니다.
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)
또한 변환하려는 모든 유형에 대한 변환 함수가 필요합니다. 예를 들어 위에서 다음과 같은 것을 사용했습니다.
strtobool = lambda s: {'true': True, 'false': False}[s]
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'}
기본 scanf http://code.activestate.com/recipes/502213-simple-scanf-implementation/ 을 구현하는 ActiveState 레시피가 있습니다 .
업데이트 : 정규식 모듈에 대한 Python 설명서 re
에는 scanf 시뮬레이션 섹션이 포함되어 있습니다.
https://docs.python.org/2/library/re.html#simulating-scanf
you can turn the ":" to space, and do the split.eg
>>> f=open("/proc/net/dev")
>>> for line in f:
... line=line.replace(":"," ").split()
... print len(line)
no regex needed (for this case)
Upvoted orip's answer. I think it is sound advice to use re module. The Kodos application is helpful when approaching a complex regexp task with Python.
http://kodos.sourceforge.net/home.html
If the separators are ':', you can split on ':', and then use x.strip() on the strings to get rid of any leading or trailing whitespace. int() will ignore the spaces.
There is a Python 2 implementation by odiak.
참고URL : https://stackoverflow.com/questions/2175080/sscanf-in-python
'Development Tip' 카테고리의 다른 글
팬더 시리즈를 필터링하는 방법 (0) | 2020.12.13 |
---|---|
다른 활성 Homebrew 프로세스가 이미 진행 중입니다. (0) | 2020.12.13 |
[UILabel copyWithZone :] : 인식 할 수없는 선택기가 인스턴스로 전송되었습니다. (0) | 2020.12.13 |
XML에서 JAXB 클래스를 생성하는 방법 (0) | 2020.12.12 |
C ++ CRTP (정적 다형성) 및 파생 클래스의 typedef 사용 (0) | 2020.12.12 |