7

私はこのような文字列を持っています:

"MSE 2110, 3030, 4102"

出力したい:

[("MSE", 2110), ("MSE", 3030), ("MSE", 4102)]

これは私のやり方ですが、まだ完全には理解していません。

def makeCourseList(str, location, tokens):
    print "before: %s" % tokens

    for index, course_number in enumerate(tokens[1:]):
        tokens[index + 1] = (tokens[0][0], course_number)

    print "after: %s" % tokens

course = Group(DEPT_CODE + COURSE_NUMBER) # .setResultsName("Course")

course_data = (course + ZeroOrMore(Suppress(',') + COURSE_NUMBER)).setParseAction(makeCourseList)

これは以下を出力します:

>>> course.parseString("CS 2110")
([(['CS', 2110], {})], {})
>>> course_data.parseString("CS 2110, 4301, 2123, 1110")
before: [['CS', 2110], 4301, 2123, 1110]
after: [['CS', 2110], ('CS', 4301), ('CS', 2123), ('CS', 1110)]
([(['CS', 2110], {}), ('CS', 4301), ('CS', 2123), ('CS', 1110)], {})

これはそれを行う正しい方法ですか、それとも私は完全にオフですか?

また、の出力は完全に正しくありません。互いに同じ形式course_dataのシンボルのリストを出力したいと思います。course現在、最初のコースは他のコースとは異なります。(これにはがあり{}ますが、他にはありません。)

4

4 に答える 4

16

このソリューションは、解析時に部門を記憶し、数値が見つかったときに (dept,coursenum) タプルを発行します。

from pyparsing import Suppress,Word,ZeroOrMore,alphas,nums,delimitedList

data = '''\
MSE 2110, 3030, 4102
CSE 1000, 2000, 3000
'''

def memorize(t):
    memorize.dept = t[0]

def token(t):
    return (memorize.dept,int(t[0]))

course = Suppress(Word(alphas).setParseAction(memorize))
number = Word(nums).setParseAction(token)
line = course + delimitedList(number)
lines = ZeroOrMore(line)

print lines.parseString(data)

出力:

[('MSE', 2110), ('MSE', 3030), ('MSE', 4102), ('CSE', 1000), ('CSE', 2000), ('CSE', 3000)]
于 2010-05-31T17:44:42.480 に答える
5

これは正しい方法ですか、それとも完全にオフですか?

これは 1 つの方法ですが、もちろん他の方法もあります (たとえば、解析アクションとして 2 つのバインドされたメソッドを使用します。つまり、メソッドが属するインスタンスは状態を保持できます。1 つは学科コード用、もう 1 つはコース番号用です)。

呼び出しの戻り値は、parseStringあなたの意志に曲げるのは難しいです (ただし、十分に暗い魔法がそれを行うと確信しており、Paul McGuire がその方法を説明するのを楽しみにしています;-)。 ..:

from pyparsing import *

DEPT_CODE = Regex(r'[A-Z]{2,}').setResultsName("DeptCode")
COURSE_NUMBER = Regex(r'[0-9]{4}').setResultsName("CourseNumber")

class MyParse(object):
  def __init__(self):
      self.result = None

  def makeCourseList(self, str, location, tokens):
      print "before: %s" % tokens

      dept = tokens[0][0]
      newtokens = [(dept, tokens[0][1])]
      newtokens.extend((dept, tok) for tok in tokens[1:])

      print "after: %s" % newtokens
      self.result = newtokens

course = Group(DEPT_CODE + COURSE_NUMBER).setResultsName("Course")

inst = MyParse()
course_data = (course + ZeroOrMore(Suppress(',') + COURSE_NUMBER)
    ).setParseAction(inst.makeCourseList)
ignore = course_data.parseString("CS 2110, 4301, 2123, 1110")
print inst.result

これは以下を発行します:

before: [['CS', '2110'], '4301', '2123', '1110']
after: [('CS', '2110'), ('CS', '4301'), ('CS', '2123'), ('CS', '1110')]
[('CS', '2110'), ('CS', '4301'), ('CS', '2123'), ('CS', '1110')]

あなたの仕様を正しく読めば、これはあなたが必要としているもののようです。

于 2010-05-31T02:16:17.700 に答える
-1
data = '''\
MSE 2110, 3030, 4102
CSE 1000, 2000, 3000'''

def get_courses(data):
    for row in data.splitlines():
        department, *numbers = row.replace(",", "").split()
        for number in numbers:
            yield department, number

これにより、コースコードのジェネレーターが提供されます。必要に応じてリストを作成するlist()か、直接反復することができます。

于 2016-02-08T21:31:03.907 に答える
-1

もちろん、みんな大好きPyParsingです。この分割のような簡単なものについては、理解するのが非常に簡単です。

data = '''\
MSE 2110, 3030, 4102
CSE 1000, 2000, 3000'''

all = []
for row in data.split('\n'):
        klass,num_l = row.split(' ',1)
        all.extend((klass,int(num)) for num in num_l.split(','))
于 2012-03-05T23:37:12.567 に答える