次のコードサンプルは、必要なものを実現します(@PaulMcGuireによって提案された以前のバージョンよりも改善されています)。
from __future__ import print_function
from pyparsing import CharsNotIn, Group, LineEnd, OneOrMore, Word, ZeroOrMore
from pyparsing import delimitedList, nums
SPACE_CHARS = ' \t'
word = CharsNotIn(SPACE_CHARS)
space = Word(SPACE_CHARS, exact=1)
label = delimitedList(word, delim=space, combine=True)
# an alternative contruction for 'label' could be:
# label = Combine(word + ZeroOrMore(space + word))
value = Word(nums)
line = label('label') + Group(OneOrMore(value))('values') + LineEnd().suppress()
text = """
string 0 1 10
string with white space 0 10 30
string9 with number 9 10 20 50
string_ with underline 10 50 1
(string with parentese) 50 20 100
""".strip()
print('input text:\n', text, '\nparsed text:\n', sep='\n')
for line_tokens, start_location, end_location in line.scanString(text):
print(line_tokens.dump())
次の出力を提供します。
input text:
string 0 1 10
string with white space 0 10 30
string9 with number 9 10 20 50
string_ with underline 10 50 1
(string with parentese) 50 20 100
parsed text:
['string', ['0', '1', '10']]
- label: string
- values: ['0', '1', '10']
['string with white space', ['0', '10', '30']]
- label: string with white space
- values: ['0', '10', '30']
['string9 with number 9', ['10', '20', '50']]
- label: string9 with number 9
- values: ['10', '20', '50']
['string_ with underline', ['10', '50', '1']]
- label: string_ with underline
- values: ['10', '50', '1']
['(string with parentese)', ['50', '20', '100']]
- label: (string with parentese)
- values: ['50', '20', '100']
label
解析された値は、最初の列(上記の例で名前が付けられた)をキーとして、残りの列(values
上記の名前)のリストを次のdict
理解度の値として持つ辞書として取得できます。
{label: values.asList() for label, values in line.searchString(text)}
ここでline
、およびtext
は上記の例の変数であり、次の結果を生成します。
{'(string with parentese)': ['50', '20', '100'],
'string': ['0', '1', '10'],
'string with white space': ['0', '10', '30'],
'string9 with number 9': ['10', '20', '50'],
'string_ with underline': ['10', '50', '1']}