Извлечение набора последовательностей из списка в python с использованием res, не дающих ожидаемого результата

#python #regex

#python #регулярное выражение

Вопрос:

У меня есть следующий список, состоящий из символьных элементов в python

   LIST1=["AR BR_16_0138244", "AR # BR_16_0138254","AR BR_16_0138264, HHGG AR BR_16_0138264", "AR 
  R_16_01382649" ,"AADSFG AR # R_16_01382679 AR # R_16_01382679" ]
  

В этом списке шаблон AR является постоянным, за которым следует буквенно-цифровая последовательность, начинающаяся с BR_ или R_. Я хотел бы извлечь уникальный список из приведенного выше, и конечный результат должен быть следующим

  ["BR_16_0138244", "BR_16_0138254", "BR_16_0138264", "R_16_01382649", "R_16_01382679"]
  

Как мне этого добиться. Я попробовал следующее

 import re
res = [x for x in LIST1 if re.search("R_", x)] 
print(res)
  

Это приводит

  ['AR BR_16_0138244', 'AR # BR_16_0138254', 'AR BR_16_0138264, HHGG AR BR_16_0138264', 'AR 
 R_16_01382649', 'AADSFG AR # R_16_01382679 AR # R_16_01382679']
  

и не ожидаемый результат

Я прошу кого-нибудь взглянуть

Комментарии:

1.Я думаю, вы берете всю строку целиком, если re.search может найти совпадение, но вы могли бы взять совпадение вместо этого (bB?R_w )(?!.*1) regex101.com/r/Drb365/1

2. Боюсь, что это возвращает пустой список.

3. Попробуйте это [sub[sub.index("R_")-1:] for sub in LIST1]

Ответ №1:

Вы получаете полное совпадение, потому что в коде вы проверяете, есть ли совпадение в re.search.

Что вы можете сделать вместо этого, так это вывести само уникальное совпадение, сопоставив необязательный символ B, за которым следуют символы R_ и 1 word.

Зафиксируйте совпадение в группе 1 и используйте отрицательный прогноз, чтобы утверждать, что записанное больше не встречается в строке.

 (bB?R_w )(?!.*1)
  

Демонстрация регулярного выражения | Демонстрация Python

Например

 import re

LIST1=["AR BR_16_0138244", "AR # BR_16_0138254","AR BR_16_0138264, HHGG AR BR_16_0138264", "AR R_16_01382649" ,"AADSFG AR # R_16_01382679 AR # R_16_01382679" ]

pattern = r"(bB?R_w )(?!.*1)"
for s in LIST1:
    m = re.search(pattern, s)
    if m:
        print(m.group(1))
  

Вывод

 BR_16_0138244
BR_16_0138254
BR_16_0138264
R_16_01382649
R_16_01382679
  

Другой вариант — использовать re.findall для получения всех совпадений, а затем в конце преобразовать результат в набор и список, чтобы удалить дубликаты.

 import re

LIST1=["AR BR_16_0138244", "AR # BR_16_0138254","AR BR_16_0138264, HHGG AR BR_16_0138264", "AR R_16_01382649" ,"AADSFG AR # R_16_01382679 AR # R_16_01382679" ]

pattern = r"bB?R_w "
result = []
for s in LIST1:
    result  = re.findall(pattern, s)

print(list(set(result)))
  

Демонстрация Python

Комментарии:

1. Спасибо, сэр. Будет ли это работать независимо от длины каждого элемента в списке и позиции ожидаемой последовательности

2. @Raghavanvmvs Длина элемента не имеет значения, пока шаблон соответствует ему. Позиция в строке не имеет значения, поскольку в первом примере используется уникальное совпадение с текущим элементом в итерации. Второй пример берет все совпадения, добавляет их к результату, а затем превращает его в список только с уникальными значениями.