1

次のように、数字がコロンとスペースで区切られたテキスト ファイルがあるとします。

0:-83 1: -51 2: -69 3: -82 4: -85 8: -90 9: -69 QUAD
0:-88 1: -88 2: -98 3: -75 4: -42 5: -71 6: -89 7: -28 8: -83 9: -78 STADIUM

ペアは、コロンで区切られた 2 つの数値として定義されます。スペースは、数値のペアを任意に中断します。

現在、私は以下を持っています。

with open('data.txt') as file:
  lines = file.read().splitlines()
for line in lines: 
  line = line[:-1]  
  # What is the regex I should be using? 
  # data = re.split(r'[:\s]',line) includes the space after the colon if it exists

各行が各タプルがペアであるタプルのリストとして保存されるように、テキスト ファイルを解析する最良の方法は何ですか?

4

3 に答える 3

3

次の正規表現は、グループ内の数値のペア (マイナス記号を含む) を提供します。

r'\b(-?\d+)\s*:\s*(-?\d+)\b'

これは、単語境界 ( \b)、数字のセット (-前にオプションのマイナス記号を含む)、オプションの空白で囲まれたコロン、オプションのマイナス記号を含む別の数字のセット、単語の境界に一致します。

デモ:

>>> import re
>>> numpairs = re.compile(r'\b(-?\d+)\s*:\s*(-?\d+)\b')
>>> example = '0:-83 1: -51 2: -69 3: -82 4: -85 8: -90 9: -69 QUAD'
>>> numpairs.findall(example)
[('0', '-83'), ('1', '-51'), ('2', '-69'), ('3', '-82'), ('4', '-85'), ('8', '-90'), ('9', '-69')]

おそらく、一度にすべての行をメモリに到達させたくないでしょう。ファイルを1行ずつループするだけです:

import re
numpairs = re.compile(r'\b(-?\d+)\s*:\s*(-?\d+)\b')
with open('data.txt') as file:
    for line in file:
        for pair in numpairs.findall(line):
            print pair

上記のコードが機能するために改行を削除する必要はありませんが、削除する場合はline.strip()代わりにline[:-1].

于 2012-09-18T08:21:24.090 に答える
1

うーん... 正規表現?なんで?

このようなものはどうですか:

result = [] # list of tuples
for line in your_file:
    fields = line.split(':')
    first = int(fields[0].strip())
    fields = fields[1:] # remove first field
    for field in fields:
        last, new_first = [int(x.strip()) for x in field.split(':')]
        result.append((first, last))
        first = new_first

...しかし、最後のフィールド (QUAD、STADION) はどうですか? あなたは今それを処理できるはずですが...

于 2012-09-18T08:38:10.597 に答える
0

まず、コーディングがはるかに簡単for line in file: です。Martijn の正規表現を使用して数値を取得できます。

for line in file:
    marker = line.split()[-1]
    numbers = re.findall(r'\b(\d+)\s*:\s*(\d+)\b', line)
于 2012-09-18T08:27:01.807 に答える