Задать вопрос
@YoungSkipper

И все же sscanf в Python — или парсинг простых строк?

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


(full_name, age, coof1, coof2) = «Name Surname 25 1/2».sscanf("{str} {int} {int}/{int}")

(coof1,coof2) = «1/2».sscanf("{int}/{int}")

(date, place) = «8:30 Place».sscanf("{datetime} {str}")


Ну и если не парситься, то как-то получать ошибку — мол не сматчилось…


Есть что-то подобное?


Если нет, то как все же правильно делать, как я понимаю есть следующие варианты


1. Использовать модуль, который эмулирует sscanf — не фиги не декларативно и не функционально как-то :)

2. Использовать регэкспы — нужно синтаксис вспоминать, и так-то много кода, создать регэксп, скомпилять, использовать

3. Что-то еще?
  • Вопрос задан
  • 5686 просмотров
Подписаться 3 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 5
leventov
@leventov
import re

def scan_compile(pattern):
    pattern = pattern.replace('{str}', '(.+?)')
    return re.compile(pattern.replace('{int}', '(\d+)'))

def scan_match(r, s):
    match = r.match(s)
    return [int(g) if g.isdigit() else g
            for g in match.groups()]

>>> from scan_match import *
>>> r = scan_compile("{str} {int} {int}/{int}")
>>> scan_match(r, 'Mary Rose Jesus 12 24/32')
['Mary Rose Jesus', 12, 24, 32]
Ответ написан
Можете глянуть в сторону pyparsing и похожих утилит по парсингу тескта (синтаксическим анализаторам).
Ответ написан
Lerg
@Lerg
Defold, Corona, Lua, GameDev
@YoungSkipper Автор вопроса
О! Регексы, но в красиво обвернуто. Собственно библиотеки которые эмулируют sscanf делают примерно тоже самое, напрмер — code.activestate.com/recipes/502213-simple-scanf-implementation/
Ответ написан
Комментировать
@YoungSkipper Автор вопроса
Но в целом что-то такое подойдет, все свое — легче контролировать если что… Только открытый вопрос что делать со сложными типа данных — типа float или datetime.
Для float он из примера можно взять — ""([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)" — но жесть же :)
Да и с int проблема — такой вариант если в строке будет 0xAB уже не подойдет — в моем конкретно случае это не нужно… Но как бы потом не забыть, а то маленькие утилитки разрастаться имеют тенденцию :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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