Pyparsing - где порядок маркеров в непредсказуемом

Я хочу смочь вытащить тип и количество букв от части текста, где буквы могли быть в любом порядке. Существует некоторое другое продолжение парсинга, которое у меня есть работа, но этому биту озадачили меня!

input -> result
"abc" -> [['a',1], ['b',1],['c',1]]
"bbbc" -> [['b',3],['c',1]]
"cccaa" -> [['a',2],['c',3]]

Я мог использовать поиск или просканировать и повториться для каждой возможной буквы, но являюсь там очевидным способом выполнения его?

Это - насколько я добрался:

from pyparsing import *


def handleStuff(string, location, tokens):

        return [tokens[0][0], len(tokens[0])]


stype = Word("abc").setParseAction(handleStuff)
section =  ZeroOrMore(stype("stype"))


print section.parseString("abc").dump()
print section.parseString("aabcc").dump()
print section.parseString("bbaaa").dump()
7
задан PhoebeB 25 January 2010 в 18:01
поделиться

5 ответов

Убедитесь, что элемент непосредственно вложен под тэг тела, используйте css с абсолютным положением и верхом: 0;

По путь фиксированный используется подавляющим большинством браузеров.

-121--4904055-

Вы можете попробовать HTML-WikiConverter

-121--1858928-

Мне не было ясно из вашего описания, можно ли смешивать входные символы, как «ababc», поскольку во всех ваших тестовых случаях буквы всегда группировались вместе. Если буквы всегда сгруппированы вместе , можно использовать этот код анализа:

def makeExpr(ch):
    expr = Word(ch).setParseAction(lambda tokens: [ch,len(tokens[0])])
    return expr

expr = Each([Optional(makeExpr(ch)) for ch in "abc"])

for t in tests:
    print t,expr.parseString(t).asList()

Каждая конструкция заботится о совпадении не в порядке, и Word (ch) обрабатывает повторение 1 к n. Действие синтаксического анализа обеспечивает преобразование проанализированных токенов в кортежи (символ, счет).

6
ответ дан 6 December 2019 в 10:50
поделиться

Если вы хотите, если вы хотите чистоципарировать подход, это ощущается вправо:

from pyparsing import *

# lambda to define expressions
def makeExpr(ch):
    expr = Literal(ch).setResultsName(ch, listAllMatches=True)
    return expr

expr = OneOrMore(MatchFirst(makeExpr(c) for c in "abc"))
expr.setParseAction(lambda tokens: [[a,len(b)] for a,b in tokens.items()])


tests = """\
abc
bbbc
cccaa
""".splitlines()

for t in tests:
    print t,expr.parseString(t).asList()

Отпечатки:

abc [['a', 1], ['c', 1], ['b', 1]]
bbbc [['c', 1], ['b', 3]]
cccaa [['a', 2], ['c', 3]]

, но это начинает попасть в непонятный код кода, поскольку она зависит от некоторых из Больше тайных особенностей Pyparding. В общем, мне нравятся счетчики частоты, которые используют defaultdict (еще не пробовали счетчик), так как это довольно ясно, что вы делаете.

2
ответ дан 6 December 2019 в 10:50
поделиться

Мне нравится однострочное решение Леннарта .

Алекс упоминает еще один отличный вариант , если вы используете 3.1

, еще один вариант - это коллекции .Defaultdict :

>>> from collections import defaultdict
>>> mydict = defaultdict(int)
>>> for c in 'bbbc':
...   mydict[c] += 1
...
>>> mydict
defaultdict(<type 'int'>, {'c': 1, 'b': 3})
3
ответ дан 6 December 2019 в 10:50
поделиться

Одно решение:

text = 'sufja srfjhvlasfjkhv lasjfvhslfjkv hlskjfvh slfkjvhslk'
print([(x,text.count(x)) for x in set(text)])

Никакой обработки, но, похоже, это перебор.

6
ответ дан 6 December 2019 в 10:50
поделиться

Pyparding Apart - в Python 3.1, Collections.counter делает такие подсчетные задачи действительно легкими. Хорошая версия Counter для Python 2 можно найти здесь .

1
ответ дан 6 December 2019 в 10:50
поделиться
Другие вопросы по тегам:

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