Неправильно в разборе разреженного ARFF с pyparsing

1

все

Я нашел фрагмент кода для анализа простого файла ARFF, и я хочу изменить его, чтобы он соответствовал разреженному ARFF, данные которого выглядят следующим образом:

@data
{0 12,4 37,8 First,20 'Some Thing'} 
{0 12,13 First,28 'Some Thing'}

вот код:

def ParseFromSimpleARFF(data):
    arffFormat = Forward()
    E = CaselessLiteral("E")
    comment = '%' + restOfLine
    relationToken = Keyword('@RELATION', caseless=True)
    dataToken = Keyword('@DATA', caseless=True)
    attribToken = Keyword('@ATTRIBUTE', caseless=True)
    ident = Word( alphas, alphanums + '_-' ).setName('identifier')
    relation = Suppress(relationToken) \
               + ident.setResultsName('relation')    
    classDomain = Suppress('{') \
                  + Group(delimitedList(ident.setResultsName('domain'))).setResultsName('domains') + Suppress('}')
    attribute = Group(Suppress(attribToken)
                + Word(alphas).setResultsName('attrname')+(Word(alphas)|classDomain).setResultsName('type')).setResultsName('attribute')            
    arithSign = Word("+-",exact=1)
    realNum = Combine( Optional(arithSign) 
              + (Word( nums ) + "." + Optional( Word(nums) )|( "." + Word(nums) )) 
              + Optional( E + Optional(arithSign) + Word(nums) ))

    **#dataList = Group(delimitedList(realNum|ident)).setResultsName('record')
    dataList = Suppress('{') + Group( delimitedList(realNum|ident)).setResultsName('record')  + Suppress('}')**
    arffFormat << ( relation
                   + OneOrMore(attribute).setResultsName('attributes')
                   + dataToken
                   + OneOrMore(dataList).setResultsName('records')).setResultsName('arffdata')

    simpleARFF = arffFormat
    simpleARFF.ignore(comment)
    tokens =  simpleARFF.parseString(data) 
    return tokens

но он не работает

Я думаю, что должен сказать программе идентифицировать withtespace, но я не знаю, как

Большое спасибо

Теги:
pyparsing
arff

1 ответ

2
Лучший ответ

Нет, нет, нет! Большая часть pyparsing заключается в том, что "пробелы происходят"! Если вы не делаете что-то сложное при анализе на основе indentation- или ориентированных данных line-, оставьте пробел из определения парсера.

Ваша проблема в том, что то, что вы определяете как список данных, не соответствует спискам, которые вы им даете. Каждый элемент comma-, ограниченный в списке, представляет собой пару значений, которые, по-видимому, разрешают числа или цитируемые строки. Поэтому определите dataList как:

dataCell = realNum|ident|quotedString
dataList = Suppress('{') + Group( delimitedList(Group(dataCell + dataCell)))  + Suppress('}')

Некоторые другие биты:

  • нет необходимости перенаправлять объявление arffFormat как Forward(). Это необходимо, только если данные будут вложены в рекурсивные структуры, то есть данные, содержащие подданные. В вашем примере этого нет, просто определите arffFormat в конце с помощью arffFormat = (...etc.

  • x.setResultsName('name') был заменен просто x('name'), действительно очищает код парсера

  • Вы определяете realNum (который требует десятичную точку), но имеют только целые числа в вашем примере. Я отошел от создания выражений типа realNum-, в пользу использования локализованного регулярного выражения: realNum = Regex(r"[+-]?\d+(\.\d*)?([Ee][+-]?\d+)?") предоставит вам выражение, которое примет целое или действительное число. Это также позволит вам удалить другие отвлекающие элементы, такие как arithSign.

Вы также можете переходить за борт в именах результатов. Я думаю, что это даст вам довольно хорошее представление о ваших данных и даст красивую структуру навигации simple- to- в конце:

arffFormat = ( relation
               + OneOrMore(attribute)('attributes')
               + dataToken
               + OneOrMore(dataList)('records'))('arffdata')
  • 0
    Я так взволнован, что я думаю, что вы автор Pyparsing! ты? Я попробую то, что ты скажешь, и узнаешь больше о pyparsing, потому что я нахожу это очень полезным! спасибо за ваш ответ и вашу прекрасную работу!
  • 0
    Да, я автор pyparsing, я рад, что вы нашли это полезным! :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню