Home > Net >  replace two different strings with two different ones in single text file (on condition- replace sec
replace two different strings with two different ones in single text file (on condition- replace sec

Time:02-18

I have a text file "sample.txt" as follows,

//this is text file
typedef enum {
  STOP_CM
} PMN_t;

typedef struct {
   Bake_t Pr[12];
   Mse_t Pr[1]
} VmCdn_t;

typedef struct {
   Sets_t Pr[1];
} McMt_t;

And I want to make the "sample.txt" as follows,

//this is text file
typedef enum {
  STOP_CM
} PMN_t;

PACK(typedef struct {
   Bake_t Pr[12];
   Mse_t Pr[1]
} VmCdn_t);

PACK(typedef struct {
   Sets_t Pr[1];
} McMt_t);

So basically, I want to PACK only structures in the file and add closing bracket at the end. Please suggest. I tried as Follows,


def readfile(filename):
    fin = open(filename,"rt")
    data = fin.read()
    data = data.replace('typedef struct {','PACK(typedef struct {')
    for line in data:
        if ("typedef struct {\n" in line):
            result = (re.sub(r'_t.*$', '_t);', line))
    fin.close()
    return result

def writedata(filename):
    data = readfile(filename)
    fin = open(filename,"wt")
    fin.write(data)
    fin.close()

#-----------------------------------------------

if __name__ == '__main__':
    filename1="sample.txt"
    writedata(filename1)

but it is not working as expected. please suggest.

CodePudding user response:

You can do this with:

import re

with open('sample.txt', 'r') as input:
    line = input.read()
    line = re.sub(r'(typedef struct {[^}] \})([^;] );', "PACK(\\1\\2);", line, flags=re.M)
    print(line)
"""
this prints the following:
//this is text file
typedef enum {
  STOP_CM
} PMN_t;

PACK(typedef struct {
   Bake_t Pr[12];
   Mse_t Pr[1]
} VmCdn_t);

PACK(typedef struct {
   Sets_t Pr[1];
} McMt_t);
"""

Explanation:

pattern: (typedef struct {[^}] \})([^;] );
replacement: "PACK(\\1\\2);"
flags: re.M

pattern:
(                   1st capture group
typedef struct {    matches this exact line
[^}]                matches one or more of anything that is not '}'
\}                  matches the closing '}'
)                   closing of 1st capture group
(                   2nd capture group
[^;]                matches one or more of anything that is not ';'
)                   closing of 2nd capture group
;                   matches ';'

replacement:
"PACK(\\1\\2);"
here \\1 and \\2 refer to the 1st and 2nd capture groups, so basically this wraps group 1 and 2 between PACK().

flag: re.M
The multiline input flag.

You can test this regex here: https://regex101.com/r/1yR4k6/1

  • Related