Редактировать и записывать результаты pyparser - PullRequest
1 голос
/ 28 мая 2020

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

pyparser позволяет мне определить синтаксис этого файла и создать вложенную структуру Group (), полную именованных атрибутов в каждый раздел. Но моя цель - иметь возможность прочитать файл, внести некоторые изменения и записать его обратно для повторного импорта в инструмент.

Есть ли хороший способ изменить ParseResults или превратить ParseResults в какой-то изменяемой структуры, которую я могу изменить с помощью доступа к именованному атрибуту и ​​записать обратно? Или мне в основном придется повторить все свое определение грамматики в дополнительном специальном коде c, чтобы вернуть порядок, который я ввел?

Пример формата файла ниже. Это одна физическая часть, как определено в этом разделе. Во второй строке, например, написано, что ниже 4 "части" (ОТКРЫТО / ЗАКРЫТО), а затем 2 "текста" (ЗНАЧЕНИЕ).

SOT\23           I 
37147500 38100000  4  3 1 0 2
OPEN   4   381000 0   1   
190500 762000
190500 1143000
2857500 1143000
2857500 -381000
OPEN   2   381000 0   1   
190500 -838200
190500 -1790700
OPEN   4   381000 0   1   
190500 -3429000
190500 -3810000
2857500 -3810000
2857500 -2286000
CLOSED 5   38100 0   20  
-2476500 2095500
5715000 2095500
5715000 -4762500
-2476500 -4762500
-2476500 2095500
VALUE     3810000     3810000   0.000  1     3810000      381000 N   LEFT   DOWN
Regular <Romansim Stroke Font>
Ref.Des.
VALUE     3810000     3810000   0.000  1     3810000      381000 N   LEFT     UP
Regular <Romansim Stroke Font>
Part Type
T0     0     0     0     1 
T0     -2667000 0     -2667000 2 
T3200400 -1333500 3200400 -1333500 3 
PAD 0 3
-2 1143000 RF  0.000 1905000 0   0   0  
-1 0   R  
0  0   R  

1 Ответ

0 голосов
/ 12 июля 2020

Поскольку вы упоминаете Group и ParseResults, я предполагаю, что вы используете pyparsing. Я обычно ищу тег "pyparsing" для вопросов о pyparsing. Вы можете попробовать реализовать свои изменения в действии синтаксического анализа, а затем использовать transformString для автоматического изменения.

Вы не описали, какие изменения вы можете захотеть внести, поэтому я вообразил, что значения для каждого OPEN и CLOSED были парами XY, и вы, возможно, захотите преобразовать, переведя все значения на + 10000.

Для этого начните с написания парсера только для OPEN/CLOSED разделы. (Мы используем pyparsing_common.signed_integer для анализа значений, что также будет выполнять преобразование str-to-int.)

import pyparsing as pp
ppc = pp.pyparsing_common

open_closed_expr = (pp.oneOf("OPEN CLOSED") + pp.restOfLine 
                    + (ppc.signed_integer * 2)[...]("pairs"))

Затем определите действие синтаксического анализа, чтобы внести это изменение:

# define a parse action to add 10000 to every integer pair value
def modify_integer_pairs(tokens):
    updated_pair_values = [x + 10000 for x in tokens.pairs]
    
    # create an updated string to return
    first_line = " ".join(tokens[:2])
    pairs_string = "\n".join("{} {}".format(*updated_pair_values[i:i+2])
                             for i in range(0, len(updated_pair_values), 2))
    return  = first_line + "\n" + pairs_string

open_closed_expr.addParseAction(modify_integer_pairs)

Попробуйте, используя transformString:

updated_text = open_closed_expr.transformString(text)
print(updated_text)

Дает:

SOT\23           I 
37147500 38100000  4  3 1 0 2
OPEN    4   381000 0   1   
200500 772000
200500 1153000
2867500 1153000
2867500 -371000
OPEN    2   381000 0   1   
200500 -828200
200500 -1780700
OPEN    4   381000 0   1   
200500 -3419000
200500 -3800000
2867500 -3800000
2867500 -2276000
CLOSED  5   38100 0   20  
-2466500 2105500
5725000 2105500
5725000 -4752500
-2466500 -4752500
-2466500 2105500
VALUE     3810000     3810000   0.000  1     3810000      381000 N   LEFT   DOWN
Regular <Romansim Stroke Font>
Ref.Des.
VALUE     3810000     3810000   0.000  1     3810000      381000 N   LEFT     UP
Regular <Romansim Stroke Font>
Part Type
T0     0     0     0     1 
T0     -2667000 0     -2667000 2 
T3200400 -1333500 3200400 -1333500 3 
PAD 0 3
-2 1143000 RF  0.000 1905000 0   0   0  
-1 0   R  
0  0   R  
...