re.match(r"^1?$|^(11+?)\1+$", "1" * num) == None
<=> num е просто
- Частта
^1?$
match-ва нула или една единици. Съответно ако
num == 0
илиnum == 1
ще има match и => резултатът отre.match
няма да е None
=> резултатът от изразът ще бъде False, което е коректно поведение,
тъй като 0 и 1 не са прости числа. - Частта
^(11+?)\1+$
върши същинската работа.
групата(11+?)
търси 2 или повече единици по non-greedy начин
(опитва се да хване възможно най-малко единици).\1+
пък търси
едно или повече повторения на вече намерената група. Ако се намерят
такива едно или повече повторения, примерноk >= 1
,
то следва, че в целият низ"1" * num
имак+1 >= 2
групи от еднакъв брой единици
(например от m единици) иm >= 2
. Получихме k групи po m единици.
Тогаваnum == k*m
и е съставно.
Ако пък няма match =>"1" * num
не може да се разбие на групи единици с равен
брой елементи <=> num няма делители.
Това че използваме non-greedy match-ване значи, че на практика
обхождаме възможните дължини на групи във възходящ ред.
Ако не се направи това изразът ще хванеnum//2
единици и така
пропускаме проверката на доста от възможните делители.
Важно е да се отбележи, че и двете части почват с ^
и завършват с $
<=> проверяваме само целият string.