使用Python正则表达式提取文件中的子字符串

时间:2019-06-10 13:09:24

标签: python regex file

文件在逻辑定义的字符串块中具有n行。我正在解析每一行,并根据一些匹配条件捕获所需的数据。

我已经阅读了每一行并找到了带有以下代码的块:

#python
    for lines in file.readlines():
        if re.match(r'block.+',lines)!= None:
            block_name = re.match(r'block.+', lines).group(0)
            # string matching code to be added here

输入文件:

line1    select KT_TT=$TMTL/$SYSNAME.P1
line2    . $dhe/ISFUNC sprfl tm/tm1032 int 231
line3    select IT_TT=$TMTL/$SYSNAME.P2
line4    . $DHE/ISFUNC ptoic ca/ca256 tli 551
         .....
         .....


line89   CALLING IK02=$TMTL/$SYSNAME.P2
line90   CALLING KK01=$TMTL/$SYSNAME.P1

每个步骤的匹配条件和预期输出:

  1. 在读取行时,匹配单词“ / ISFUNC”,并从最后一个字符中获取字符,直到匹配“ /”,然后将其保存到变量中。预期为o / p-> tm1032 int 231,ca256 tli 551(在第2行和第4行等中找到匹配的字符串)
  2. 找到ISFUNC后,读取紧接的前一行并从该行获取数据,从最后一个字符开始,直到匹配“ /”,然后将其保存到变量中。预期o / p-> $ SYSNAME.P1和$ SYSNAME.P2(第1行和第3行,等等)
  3. 继续向下阅读各行,查找以“ CALLING”开头的行,“ /”之后的最后一个字符串应与步骤2的o / p($ SYSNAME.P1和$ SYSNAME.P2)匹配。只需在调用单词后捕获数据并保存。预期o / p-> KK01(第90行)和IK02(第89行)

最终输出应为

FUNC             SYS            CALL
tm1032 int 231   $SYSNAME.P1    KK01
ca256 tli 551    $SYSNAME.P2    IK02 

2 个答案:

答案 0 :(得分:0)

如果仅需要最后一个斜杠旁边的文本,则完全不需要正则表达式。

只需在每行上使用.split("/"),就可以得到斜杠旁边的最后一部分

sample = "$dhe/ISFUNC sprfl tm/tm1032 int 231"
sample.split("/")

将导致

['$dhe', 'ISFUNC sprfl tm', 'tm1032 int 231']

然后使用-1索引访问列表的最后一个元素以获取值

PS:找到对应的行后,请使用拆分功能

答案 1 :(得分:0)

  

在读取行时,匹配单词“ / ISFUNC”,并从最后一个字符中获取字符,直到匹配“ /”,然后将其保存到变量中。预期为o / p-> tm1032 int 231(在第2行中找到匹配的字符串)

char_list = re.findall(r'/ISFUNC.*/(.*)$', line)
if char_list:
    chars = char_list[0]
  

找到ISFUNC后,读取前一行,并从该行获取数据,从最后一个字符开始,直到匹配“ /”,然后将其保存到变量中。预期为o / p-> $ SYSNAME.P1(第1行)

这里的理想方法是(a)遍历列表索引而不是行本身(即for i in range(len(file.readlines()): ... file.readlines()[i]),或者(b)维护 last 行的副本(例如,将last_line = line放在for循环的 end 处,然后引用此表达式的最后一行:

data_list = re.findall(r'/([^/]*)$', last_line)
if data_list:
    data = data_list[0]
  

继续向下阅读各行,查找以“ CALLING”开头的行,“ /”之后的最后一个字符串应与步骤2($ SYSNAME.P1)的o / p匹配。只需在调用单词后捕获数据并保存。预期o / p-> KK01(第90行)

假设在您的示例中,您的意思是“紧接着(即直到等号之前)数据

calling_list = re.findall(r'CALLING(.*)=.*/' + re.escape(data) + '$', line) 
if calling_list:
    calling = calling_list[0]

您可以移动括号以更改要捕获的那一行的内容。 re.findall()将输出一个匹配列表,仅包括匹配括号内的位。