Как извлечь конкретные данные из строки? - PullRequest
1 голос
/ 21 мая 2019

У меня есть текстовый документ, который я хочу проанализировать.Я хочу иметь возможность получать строки между "@ 5c00 \ n" и "@ ffd2 \ n", а также между "@ ffd2 \ n" и "@"

@5c00
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
@ffd2
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
@
q

Я пытался использоватьрегулярные выражения, но это, кажется, дает мне ['', ''].

file = open("app_blink.txt","r") #app_blink.txt being the string above
contents = file.read()
data = re.findall('\n(.*)@',contents,re.M)

Я ожидал получить:

data
['81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00..
 FD 3F 03 43 00 00 00 02','14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C..
 \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14..
 5C 14 5C 14 5C 00 5C CF 0C \n']

, но на самом деле получил:

data
['','']

Ответы [ 5 ]

1 голос
/ 21 мая 2019

Вы были близки. Вместо этого вам понадобился флаг re.DOTALL и не жадное совпадение:

contents = '''\
@5c00
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
@ffd2
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
@
q
'''

import re
for x in re.findall(r'\n(.*?)@',contents,re.DOTALL):
    print(x)

Выход:

81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 

14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
0 голосов
/ 21 мая 2019

Здесь мы можем не использовать регулярные выражения, потому что это может стать немного дороже.Может быть, разделение строки будет хорошо.Например, мы можем разделить на @.

Пример

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

test_str = '''
@bb00
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02
@5c00
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 
@ffd2
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 
14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C 
@
81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 
B1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 

'''

split_str = test_str.split('@')
data=[]
for matches in split_str:
  if (matches[:4] == '5c00' or matches[:4] == 'ffd2'):
    data.append(matches[5:])


print(data)

Выход

['81 00 00 5C B1 13 3E 01 0C 43 B113 A6 00 1C 43 \ nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 \ n ', '14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \ n14 5C 14 5C 14 5C14 5C 14 5C 14 5C 14 5C 14 5C \ n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C \ n ']

0 голосов
/ 21 мая 2019

Это регулярное выражение должно работать Tryit

import re

regex = r"^[^\@].*"

test_str = ("@5c00\n81 00 00\n76 20 11\n@ffd2\n")

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

Примечание: для совместимости с Python 2.7 используйте ur "" для добавления префикса в регулярное выражение и u "" для добавления префикса тестовой строки и подстановки.

0 голосов
/ 21 мая 2019

Проверьте это регулярное выражение:

data = re.findall('^[\d \w]{2,}$',contents,re.M)

Он просто берет строки с шестнадцатеричными числами.

0 голосов
/ 21 мая 2019

Это звучит как работа для регулярных выражений!

\@[^\n]*\n([^\@]*)\n(?=\@)

Это регулярное выражение будет соответствовать:

  • Во-первых, буквальный @ знак
  • Затем любая строка символов, заканчивающаяся символом новой строки
  • Затем все, что он может найти, но не включает @: эта часть сохраняется в группе # 1
  • Затем перевод строки завершает все это
  • Наконец, принимайте, только если следующий символ @ (но не используйте этот символ)

Как пример:

>>> re.search(r'\@[^\n]*\n([^\@]*)\n(?=\@)', your_string).group(1)
'81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 '

Итак, чтобы получить список важных вещей:

>>> [m.group(1) for m in re.finditer(r'\@[^\n]*\n([^\@]*)\n(?=\@)', your_string)]
['81 00 00 5C B1 13 3E 01 0C 43 B1 13 A6 00 1C 43 \nB1 13 38 01 32 D0 10 00 FD 3F 03 43 00 00 00 02 ', '14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 14 5C \n14 5C 14 5C 14 5C 14 5C 14 5C 14 5C 00 5C CF 0C ']

Или, для более простого ответа:

re.split(r'\@[^\n]*\n', your_string)

Разделять строку всякий раз, когда вы найдете строку, начинающуюся с @.

...