如何在python中捕获正则表达式匹配上方的n行?

时间:2018-04-02 04:06:29

标签: python regex python-3.x

我有一个这样的字符串:

[01112017 110228 359][1][INFO]> Get Cash Unit Info
[01112017 110228 400][1][INFO]> ---Cash Unit Info Ready True
[01112017 110228 698][1][INFO]> Cash Unit Info - 0 Value 01  REJC  ---  0000  0000  0004  000    OK
[01112017 110228 699][1][INFO]> Cash Unit Info - 1 Value 02  RETR  ---  0000  0000  0000  000    OK
[01112017 110228 700][1][INFO]> Cash Unit Info - 2 Value 03  BILL  LKR  5000  1000  0999  001    OK
[01112017 110228 700][1][INFO]> Cash Unit Info - 3 Value 04  BILL  LKR  1000  2000  1999  001    OK
[01112017 110228 701][1][INFO]> Cash Unit Info - 4 Value 05  BILL  LKR  0500  2000  1999  001    OK
[01112017 110228 702][1][INFO]> Cash Unit Info - 5 Value 06  BILL  LKR  0100  2000  1999  001    OK
[01112017 110244 760][1][INFO]> ======================================
[01112017 110244 760][1][INFO]> TTU Back Panel Log Out

我想在字符串“TTU Back Panel Log Out”上方捕获5行。

我已经尝试过正则表达式((。* \ n){5})TTU后面板退出并输出0匹配

任何帮助将不胜感激。注意:使用库重新

Python3

4 个答案:

答案 0 :(得分:1)

在你的正则表达式中,你假设你的目标行以你的模式开头,但事实并非如此。

尽管如此,我相信您可以通过遍历各个行并使用in找到您的模式来获得更好,更易读的解决方案。

def find_lines_before_pattern(pattern, n, text):
    lines = text.splitlines()

    for lineno, line in enumerate(lines):
        if pattern in line:
            first_line = max(lineno - n, 0)
            break
    else:
        # Define your behaviour if the pattern is not found
        raise ValueError('Pattern not found')

    return lines[first_line: lineno]

text = """
some
lines
before
your
pattern
[01112017 110244 760][1][INFO]> TTU Back Panel Log Out
"""

find_lines_before_pattern('TTU Back Panel Log Out', 5, text)
# output: ['some', 'lines', 'before', 'your', 'pattern']

答案 1 :(得分:0)

试试这个(假设你的字符串被称为s):

re.findall('(.*)(?:.*\n){5}.*TTU Back Panel Log Out', s)

返回:

['[01112017 110228 700][1][INFO]> Cash Unit Info - 2 Value 03  BILL  LKR  5000  1000  0999  001    OK']

(?:.*\n){5}是一个非捕获组(由于?:),但会搜索新行前5次出现的任何字符。它前面的(.*)是您正在捕获的组

答案 2 :(得分:0)

第六行不以您的目标字符串TTU Back Panel开头 - 还有其他文字。所以你需要.*?之前:

>>> text = '''[01112017 110228 359][1][INFO]> Get Cash Unit Info
[01112017 110228 400][1][INFO]> ---Cash Unit Info Ready True''' # etc.
>>> re.search('([^\n]*\n){5}.*?TTU Back Panel', text)
<_sre.SRE_Match object; span=(312, 829), match='[01112017 110228 700][1][INFO]> Cash Unit Info - > 

答案 3 :(得分:0)

你可以尝试这种模式:

import re
pattern = r'((.*\n){5})\[\d.+\]\[1\]\[INFO\]\> TTU Back Panel Log Out'

print(re.findall(pattern,text))

输出:

[('[01112017 110228 700][1][INFO]> Cash Unit Info - 2 Value 03  BILL  LKR  5000  1000  0999  001    OK\n[01112017 110228 700][1][INFO]> Cash Unit Info - 3 Value 04  BILL  LKR  1000  2000  1999  001    OK\n[01112017 110228 701][1][INFO]> Cash Unit Info - 4 Value 05  BILL  LKR  0500  2000  1999  001    OK\n[01112017 110228 702][1][INFO]> Cash Unit Info - 5 Value 06  BILL  LKR  0100  2000  1999  001    OK\n[01112017 110244 760][1][INFO]> ======================================\n', '[01112017 110244 760][1][INFO]> ======================================\n')]
  

正则表达式信息:

以下RegEx测试[\d.+\]\[1\]\[INFO\]\> TTU Back Panel Log Out行之前可变数量的行。

  1. (.*\n)测试以\n结尾的字符串,换行符。
  2. {5}量化 这5次。
  3. ()周围确保所有行都在一个 捕获组。
  4. [\d.+\]\[1\]\[INFO\]\> TTU Back Panel Log Out是文本必须结束的字符串。