hiçbir fscanf
eşdeğer veya Java en Scanner
yoktur. En basit çözüm, kullanıcının alan ayrılmış giriş yerine yeni satır ayrımlı girişi kullanmasını gerektirmesidir, daha sonra satır satır okuyabilir ve çizgileri doğru türe dönüştürebilirsiniz.
Kullanıcı sonra muhtemelen kullanıcı girişi için bir ayrıştırıcı oluşturmalıdır daha yapısal girdi sağlamak istiyorum. Python için bazı güzel ayrıştırma kütüphaneleri vardır, örneğin pyparsing. Ayrıca, son güncelleştirme 2008 olmasına rağmen modülü de vardır.
Dış bağımlılıklara sahip olmak istemiyorsanız, giriş dizileriyle eşleştirmek için normal ifadeleri kullanabilirsiniz. Düzenli ifadeler dizeler üzerinde çalışmayı gerektirir, ancak bu sınırlama okumasını kolayca yığınlarda üstesinden gelebilirsiniz. Örneğin böyle bir şey de çoğu zaman çalışması gerekir:
import re
FORMATS_TYPES = {
'd': int,
'f': float,
's': str,
}
FORMATS_REGEXES = {
'd': re.compile(r'(?:\s|\b)*([+-]?\d+)(?:\s|\b)*'),
'f': re.compile(r'(?:\s|\b)*([+-]?\d+\.?\d*)(?:\s|\b)*'),
's': re.compile(r'\b(\w+)\b'),
}
FORMAT_FIELD_REGEX = re.compile(r'%(s|d|f)')
def scan_input(format_string, stream, max_size=float('+inf'), chunk_size=1024):
"""Scan an input stream and retrieve formatted input."""
chunk = ''
format_fields = format_string.split()[::-1]
while format_fields:
fields = FORMAT_FIELD_REGEX.findall(format_fields.pop())
if not chunk:
chunk = _get_chunk(stream, chunk_size)
for field in fields:
field_regex = FORMATS_REGEXES[field]
match = field_regex.search(chunk)
length_before = len(chunk)
while match is None or match.end() >= len(chunk):
chunk += _get_chunk(stream, chunk_size)
if not chunk or length_before == len(chunk):
if match is None:
raise ValueError('Missing fields.')
break
text = match.group(1)
yield FORMATS_TYPES[field](text)
chunk = chunk[match.end():]
def _get_chunk(stream, chunk_size):
try:
return stream.read(chunk_size)
except EOFError:
return ''
Örnek kullanım:
>>> s = StringIO('1234 Hello World -13.48 -678 12.45')
>>> for data in scan_input('%d %s %s %f %d %f', s): print repr(data)
...
1234
'Hello'
'World'
-13.48
-678
12.45
Muhtemelen bu genişletmek ve düzgün test gerekecek ancak bazı fikir edinebilirsiniz .
Giriş çok kirli/keyfi ise, ben 're' modülünü kullanma eğilimindedir; Eğer giriş yapılandırılmışsa, basitparse gibi bir ayrıştırıcı kütüphanesini tercih ederim (EBNL'nin normal ifadelerden daha kolay korunması). –
Aklınızda bir kullanım durumunuz varsa, genel bir sorgulama yapmak yerine sorunuzu güncellemek daha verimli olabilir. –
Diğer öneriler için http://stackoverflow.com/questions/2175080/sscanf-in-python adresine bakın. –