2016-03-14 2 views
2

Я почти не вижу больше для поиска google и этого сайта для решения моей проблемы.python regex find/match one or more in a string

Я хочу, чтобы выбрать одну или несколько последовательностей двух различных строк текста из строки:

например 'aSATMPA23.37aSAAWAKE----aSABATT2.05-aSASLEEPING-'

Так что я хотел бы выбрать «aSATMPA23.37», и если он есть также «aSABATT2.05».

Я попробовал следующее:

import re 
serialdata = 'aSATMPA18.5-----aSBBATT2.97-aSBSLEEPING-' 
def regex_serialdata(data):         
    GrandRegex = re.compile(r'(aS(.)(TMPA)(\d+\.\d+))|(aS(.)(BATT)(\d+\.\d+))') 
    match = GrandRegex.match(data) 

, но это останавливается только после первого матча 'aSATMPA18.5'

Далее я попытался с помощью метода 'FindAll':

def regex_serialdata(data):         
    GrandRegex = re.compile(r'(aS(.)(TMPA)(\d+\.\d+))|(aS(.)(BATT)(\d+\.\d+))')  
    match = GrandRegex.findall(data) 
    print(match) 

В результате: [('aSATMPA18.5', 'A', 'TMPA', '18.5', '', '', '', ''), ('', '', '', '', 'aSBBATT2.97', 'B', 'BATT', '2.97')]

Есть ли лучший способ сделать это?

Можно ли легко получить доступ к значениям в списке кортежей?

Обратите внимание, что я потратил часы на это и не прошу помощи легкомысленно.

Очень ценивший,

Пол

+0

извините опечатка, отредактированы. –

ответ

3
>>> a = 'aSATMPA23.37aSAAWAKE----aSATMPA15.14-aSASLEEPING-' 
>>> re.findall(r'aSATMPA\d+.\d+',a) 
['aSATMPA23.37', 'aSATMPA15.14'] 

Если Вы размещаете скобку, как показано ниже, Вы можете получить список кортежей со значениями, которые вы хотите от каждого матча:

>>> a 
'aSATMPA23.37aSAAWAKE----aSBBATT2.05-aSASLEEPING-' 
>>> b = re.findall(r'(aS)(ATMPA|BBATT)(\d+.\d+)',a) 
>>> b 
[('aS', 'ATMPA', '23.37'), ('aS', 'BBATT', '2.05')] 
>>> b[0][0] 
'aS' 
>>> b[0][1] 
'ATMPA' 
>>> b[0][2] 
'23.37' 
>>> b[1][0] 
'aS' 
>>> b[1][1] 
'BBATT' 
>>> b[1][2] 
'2.05' 
+0

спасибо за это, мне нужны частички, поэтому я могу извлечь дополнительные части данных, то есть из «aSATMPA23.37». Я хочу, чтобы 23.37 в качестве значения температуры и SA в качестве адреса устройства. –

+0

@Tullio_IRL проверить мое редактирование сейчас .. это то, что вы хотите? Потому что я не уверен, каков желаемый результат. –

+0

Да, я думаю, что все, просто немного скорректировав круглые скобки; b = re.findall (r'aS (.) (TMPA | BATT) (\ d +. \ D +) ', a) –

2

Есть ли лучший способ сделать это?

Да. Избавиться от всех ваших скобок:

import re 
serialdata = 'aSATMPA18.5-----aSBBATT2.97-aSBSLEEPING-' 
def regex_serialdata(data): 
    GrandRegex = re.compile(r'aS.TMPA\d+\.\d+|aS.BATT\d+\.\d+') 
    match = GrandRegex.findall(data) 
    print (match) 

regex_serialdata(serialdata) 

Могу ли я получить доступ к значениям в пределах списка кортежей легко?

Да. Из вашего второго примера попробуйте print(match[0][0], match[1][4]).

+0

спасибо за это, как я уже отмечал выше, мне нужно еще раз проанализировать возвращаемые значения, следовательно, круглые скобки , –

1

Попробуйте следующее регулярное выражение:

r'(aSA(?:TMPA|BATT))(\d+(?:\.\d+)?)' 

Полный код:

import re 
p = re.compile(r'(aSA(?:TMPA|BATT))(\d+(?:\.\d+)?)', re.DOTALL) 

test_str = """ 
aSATMPA23.37aSAAWAKE----aSABATT2.05-aSASLEEPING-aSATMPA23.37aSAAWAKE-- 
--aSABATT2.05-aSASLEEPING-aSATMPA23.37aSAAWAKE--- 
-aSABATT2.05-aSASLEEPING-aSATMPA23.37aSAAWAKE- 
""" 

for m in re.finditer(p, test_str): 
    print('{0:<15}{1}'.format(m.group(1), m.group(2))) 

Это будет печатать:

aSATMPA  23.37 
aSABATT  2.05 
aSATMPA  23.37 
aSABATT  2.05 
aSATMPA  23.37 
aSABATT  2.05 
aSATMPA  23.37 

См demo

Основываясь на своем входе, он будет CAPT Юр

  • aSATMPA23.37
  • aSABATT2.05
+0

отличные вещи, но есть вероятность, что существует больше значений aSATMPA23.14 или aSABATT2.50, и ваш шаблон регулярного выражения, похоже, не захватывает дальнейшие. –

+0

будет захватывать все. Я уверен – Saleem

+0

См. Еще одну демонстрацию https://regex101.com/r/tZ4kW5/2 – Saleem

0

Спасибо всем, кто ответившие и способствовали, с вашей помощью я придумал следующее:

import re 

serialdata = 'aSATMPA18.5-----aSBBATT2.97-aSBSLEEPING-' 

def regex_serialdata(data):         
    GrandRegex = re.compile(r'aS(.)(TMPA|BATT)(\d+.\d+)') 

    match = GrandRegex.findall(data) 

    print(match) 
for x, y, z in match: 
    if y == 'TMPA': 
     print('Temp is %s' % z) 
    elif y == 'BATT': 
     print('Battery is %sv' % z) 

Этот произвел следующий результат, который именно то, что я хочу:

[('A', 'TMPA', '18.5'), ('B', 'BATT', '2.97'), ('B', 'TMPA', '24.18')] 
Temp is 18.5 
Battery is 2.97v 

Я рад, что выглядит довольно :)

Большое спасибо,

Пол