Разбор текстового файла в табличные данные для обработки - PullRequest
1 голос
/ 23 мая 2019

Проблема под рукой состоит в том, чтобы проанализировать определенные данные в табличной форме, используя python. Небольшая часть данных показана ниже

Statistics indicator:0x222235

number of records = 3 

records[0]

value one = 2

value two = 5

blocks = 2

block[0] {

some irrelevant data....

value three = 4 bytes

}

block[1]{

some irrelevant data...

value three = 6 bytes

}

records[1]

value one = 3

value two = 5

blocks = 1

block[0] {

some irrelevant data....

value three = 4 bytes

}

records[2]

value one = 7

value two = 6

blocks = 2

block[0] {

some irrelevant data....

value three = 3 bytes

}

block[1]{

some irrelevant data...

value three = 4 bytes

}

Statistics indicator:0x135256

number of records = 2 

records[0]

value one = 4

value two = 8

blocks = 1

block[0] {

some irrelevant data....

value three = 6 bytes

}

records[1]

value one = 3

value two = 5

blocks = 1

block[0] {

some irrelevant data....

value three = 3 bytes

}

Как показано, данные имеют определенный шаблон. Он имеет индикатор статистики в начале каждого конкретного блока данных. Он имеет поле количества записей, чтобы указать количество записей, которые есть в блоке данных. В каждой записи «значение один» и значение два »различны. Однако существует несколько «значений три» в зависимости от количества блоков в каждой записи, которое указано полем «блоки». Проблема здесь состоит в том, чтобы расположить следующие данные в табличной форме, добавив все три значения, соответствующие конкретной записи.

Финальный стол должен выглядеть примерно так:

значение одно значение два значение три

2          5        10 

3          5         4

7          6         7

4          8         6

3          5         3

Подход, который я думаю, состоит в том, чтобы сначала найти «Индикатор статистики». Если я найду «Индикатор статистики», я буду искать количество записей и блоков, соответствующих каждой записи, для итерации по блокам и суммировать значение три, соответствующее аналогичному значению один и значение два.

Вот код, который я пытался извлечь значение одно значение два и значение три. Я еще не углубился в суммирование трех.

import re
import pandas as pd
val_dict = { 'value_one':re.compile(r'value one = (?P<value_one>.*)\n'),
           'value_two':re.compile(r'value two = (?P<value_two>.*)\n'),
           'value_three':re.compile(r'value three = (?P<value_three>.*)\n')}

def _parse_line(line):


    for key, val in val_dict.items():
        match = val.search(line)
        if match:
            return key, match
# if there are no matches
    return None, None


def parse_file(filepath):
    data = []  
    with open(filepath, 'r') as file_object:
        row = {}                                # prepare an empty row
        for line in file_object:
            key, match = _parse_line(line)
            # search for keys in the line
            if key == 'value_one':
                value_one = match.group('value_one')
                value_one = int(value_one)
                if 'value one' in row:          # we always have a full row
                    data.append(row)            # append it to the data liest
                    row = {}                    # and reset it
                row['value one'] = value_one    # we have a match: store the value in row

            if key == 'value_two':
                value_two = match.group('value_two')
                value_two = int(value_two)
                if 'value two' in row:
                    data.append(row)
                    row = {}
                row['value two'] = value_two

            if key == 'value_three':
                value_three = match.group('value_three')
                value_three = int(value_three)
                if 'value three' in row:
                    data.append(row)
                    row = {}
                row['value three'] = value_three

        if row != {}:                      # do not forget the last row
            data.append(row)
        data = pd.DataFrame(data)
        return data
if __name__ == '__main__':
    filepath = 'test3.txt'
    data = parse_file(filepath)

1 Ответ

0 голосов
/ 23 мая 2019

Здесь, может быть, мы не хотим использовать регулярные выражения.Однако, если мы можем захотеть сделать это, мы можем установить имена атрибутов в качестве левой границы и собрать желаемые цифры, возможно, с помощью выражения, похожего на:

value\s+(one|two|three)\s+=\s+([0-9]+)

Тогда остальная часть нашей проблемы можетбыть сценариемМы также можем добавить больше границ для наших выражений, если это будет необходимо.

Демо

Тест

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"value\s+(one|two|three)\s+=\s+([0-9]+)"

test_str = ("Statistics indicator:0x222235\n\n"
    "number of records = 3\n\n"
    "records[0]\n\n"
    "value one = 2\n\n"
    "value two = 5\n\n"
    "blocks = 2\n\n"
    "block[0] {\n\n"
    "some irrelevant data....\n\n"
    "value three = 4 bytes\n\n"
    "}\n\n"
    "block[1]{\n\n"
    "some irrelevant data...\n\n"
    "value three = 6 bytes\n\n"
    "}\n\n"
    "records[1]\n\n"
    "value one = 3\n\n"
    "value two = 5\n\n"
    "blocks = 1\n\n"
    "block[0] {\n\n"
    "some irrelevant data....\n\n"
    "value three = 4 bytes\n\n"
    "}\n\n"
    "records[2]\n\n"
    "value one = 7\n\n"
    "value two = 6\n\n"
    "blocks = 2\n\n"
    "block[0] {\n\n"
    "some irrelevant data....\n\n"
    "value three = 3 bytes\n\n"
    "}\n\n"
    "block[1]{\n\n"
    "some irrelevant data...\n\n"
    "value three = 4 bytes\n\n"
    "}\n\n"
    "Statistics indicator:0x135256\n\n"
    "number of records = 2\n\n"
    "records[0]\n\n"
    "value one = 4\n\n"
    "value two = 8\n\n"
    "blocks = 1\n\n"
    "block[0] {\n\n"
    "some irrelevant data....\n\n"
    "value three = 6 bytes\n\n"
    "}\n\n"
    "records[1]\n\n"
    "value one = 3\n\n"
    "value two = 5\n\n"
    "blocks = 1\n\n"
    "block[0] {\n\n"
    "some irrelevant data....\n\n"
    "value three = 3 bytes\n\n"
    "}")

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

Демо

const regex = /value\s+(one|two|three)\s+=\s+([0-9]+)/gm;
const str = `Statistics indicator:0x222235

number of records = 3

records[0]

value one = 2

value two = 5

blocks = 2

block[0] {

some irrelevant data....

value three = 4 bytes

}

block[1]{

some irrelevant data...

value three = 6 bytes

}

records[1]

value one = 3

value two = 5

blocks = 1

block[0] {

some irrelevant data....

value three = 4 bytes

}

records[2]

value one = 7

value two = 6

blocks = 2

block[0] {

some irrelevant data....

value three = 3 bytes

}

block[1]{

some irrelevant data...

value three = 4 bytes

}

Statistics indicator:0x135256

number of records = 2

records[0]

value one = 4

value two = 8

blocks = 1

block[0] {

some irrelevant data....

value three = 6 bytes

}

records[1]

value one = 3

value two = 5

blocks = 1

block[0] {

some irrelevant data....

value three = 3 bytes

}`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

RegEx

Если это выражение нежелательно, его можно изменить или изменить в regex101.com .

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

...