0

ファイルをトークンのリストに解析したい。各トークンは少なくとも 1 行で構成されますが、複数行で構成することもできます。各トークンは正規表現に一致します。入力がトークンのシーケンスでない場合 (つまり、先頭、中間、または末尾にガベージがない場合) にエラーを通知したいと考えています。入力ファイルは比較的小さいため、メモリ消費は気にしません。

Perl では、(疑似コード) のようなものを使用します。

$s = slurp_file ();
while ($s ne '') {
  if ($s =~ s/^\nsection (\d)\n\n/p) {
    push (@r, ['SECTION ' . $1, ${^MATCH}]);
  } elsif ($s =~ s/^some line\n/p) {
    push (@r, ['SOME LINE', ${^MATCH}]);
  [...]
  } else {
    die ("Found garbage: " . Dumper ($s));
  }
}

もちろん、この 1:1 を Python に移植することもできますが、これを行うためのより Pythonic な方法はありますか? (行ごとに解析してから、手作りのステート マシンをその上に構築したくありません。)

4

1 に答える 1

2

モジュールには、ここで役立つ可能性のある文書化されていないツールがあります。re次のように使用できます。

import re
import sys

def section(scanner, token):
    return "SECTION", scanner.match.group(1)

def some_line(scanner, token):
    return "SOME LINE", token

def garbage(scanner, token):
    sys.exit('Found garbage: {}'.format(token))

# scanner will attempt to match these patterns in the order listed.
# If there is a match, the second argument is called.
scanner = re.Scanner([  
    (r"section (\d+)$$", section),
    (r"some line$", some_line), 
    (r"\s+", None),  # skip whitespace
    (r".+", garbage), # if you get here it's garbage
    ], flags=re.MULTILINE)


tokens, remainder = scanner.scan('''\

section 1

some line
''')
for token in tokens:
    print(token)

収量

('SECTION', '1')
('SOME LINE', 'some line')
于 2013-06-20T13:03:51.333 に答える