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

#python #regex #attributeerror

Вопрос:

Поэтому я пытаюсь решить некоторые проблемы с кодом в течение 30 дней испытаний code hackerrank. Я должен вернуть имена вводимых данных, если у них есть электронное письмо, которое gmail.com. Так, например, входные данные могут быть:

(Число указывает количество входных строк для программы.)

 6
riya riya@gmail.com
julia julia@julia.me
julia sjulia@gmail.com
julia julia@gmail.com
samantha samantha@gmail.com
tanya tanya@gmail.com
 

и результат будет выглядеть так

 riya
julia
julia
samantha
tanya
 

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

 import math
import os
import random
import re
import sys


if __name__ == '__main__':
    N = int(input().strip())
    
    pattern = re.compile(r'([a-zA-Z]@gmail.com)')

    for N_itr in range(N):
        first_multiple_input = input().rstrip().split()

        firstName = first_multiple_input[0]

        emailID = first_multiple_input[1]
        
        matches = pattern.finditer(emailID)
        
        if matches.group(0):
            print(firstName)
 

но когда я запускаю код, я получаю сообщение об ошибке:

 Traceback (most recent call last):
  File "Solution.py", line 25, in <module>
    if matches.group(0):
AttributeError: 'callable_iterator' object has no attribute 'group'
 

Я рассматривал подобные проблемы, подобные этой, при переполнении стека, но я не мог понять ответы, это мой первый раз, когда я использую регулярное выражение, и я работаю с видео, которые я смотрел онлайн (так как я самоучка). Как я могу решить эту проблему?

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

1. re.finditer возвращает итератор объекта данных соответствия, и только объект соответствия содержит .group() метод. Сначала получите объект данных соответствия. Или используйте re.search , чтобы просто получить первое совпадение. Или здесь вы можете просто разделить строки.

2. Вы также должны повторить класс символов, иначе вы будете соответствовать одному символу ([a-zA-Z] )@gmail.com

3. Проверка того, существует ли хотя бы один алфавитный @ знак, на самом деле достаточна, если это то, что вас особенно волнует, хотя, как я указываю в своем ответе, есть и другие символы, которые вам, вероятно, тоже следует искать.

Ответ №1:

Вам не нужно регулярное выражение (или math , или random , или os ) здесь.

 import sys

number = int(sys.stdin.__next__())

for idx, line in enumerate(sys.stdin):
    if idx > number:
        break
    if '@gmail.com' not in line:
        next
    print(line.split()[0])
 

Это не совсем эквивалентно вашему коду, потому что мы не проверяем, что находится перед @ символом. Если вы хотите это сделать, вам действительно следует проверить, что разрешает Gmail (например, я думаю, что там будут разрешены цифры, возможно, точка и, возможно, некоторые другие символы, такие как подчеркивания и т. Д.).

Если вы действительно хотели использовать регулярное выражение, вероятно , не используйте finditer , которое возвращает список match объектов. Если вас интересует только первое совпадение, просто используйте re.search() вместо этого; тогда результатом будет match объект, если совпадение было, и вы можете вызвать его .group() метод.

Это также не совсем эквивалентно вашему коду, поскольку он не потерпит неудачу, если входных строк будет меньше, чем обещано в первой строке. Добавление чека для этого должно быть легким и, вероятно, хорошим упражнением.

Если ваш файл не содержит функций, if __name__ == '__main__': проверка бессмысленна. Его цель состоит в том, чтобы добавить в этот модуль другой модуль Python import , но если он не содержит ничего, что можно было бы с пользой import отредактировать, вы все равно никогда не захотите этого делать. (Более подробно, когда у вас import этого файла __name__ не будет __main__ , и поэтому весь этот код будет просто отброшен. Вы хотите вложить туда как можно меньше, и если вас волнует возможность повторного использования кода, поместите весь полезный код в классы и функции.)