【问题标题】:substring extract in a file using Python Regex使用 Python Regex 在文件中提取子字符串
【发布时间】:2019-06-10 13:09:24
【问题描述】:

一个文件在逻辑定义的字符串块中有 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)。只需在 CALLING 字之后捕获数据并保存即可。预期 o/p -> KK01(第 90 行)和 IK02(第 89 行)

最终输出应该是这样的

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

【问题讨论】:

  • 这里有什么问题?您在编写正则表达式模式方面需要帮助?

标签: python regex file


【解决方案1】:

如果您只需要最后一个斜杠旁边的文本,则根本不需要使用正则表达式。

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

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

将导致

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

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

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

【讨论】:

    【解决方案2】:

    在阅读这些行时,匹配单词“/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 匹配。只需在 CALLING 字之后捕获数据并保存即可。预期 o/p -> KK01(第 90 行)

    假设,从你的例子中,你的意思是“只是数据立即之后(即直到等号):

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

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

    【讨论】:

    • char_list = re.findall(r'/ISFUNC(.*?)/', line) - 这会获取 ISFUNC 之后的字符。即它返回'sprfl tm'。我所期望的是'tm1032 int 231'
    • 对,对不起,误会了。很容易修复 - 只需在第二个 / 之后而不是之前匹配。我已经相应地编辑了我的答案。
    • 好的,np。我刚刚编辑了我的问题,增加了 1 行输入,并带有最终预期的 o/p。输入文件可能有 n 行这样的行。我在某处缺少循环结构。
    • 没关系。要遍历列表中的索引,哪一个会更好?范围还是枚举?
    猜你喜欢
    • 2023-01-07
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多