Nazwana grupa wyrażeń regularnych „(? P <nazwa_grupy> regexp)”: co oznacza „P”?

178

W Pythonie (?P<group_name>…) składnia pozwala odwołać się do dopasowanego ciągu poprzez jego nazwę:

>>> import re
>>> match = re.search('(?P<name>.*) (?P<phone>.*)', 'John 123456')
>>> match.group('name')
'John'

Co oznacza „P”? Nie mogłem znaleźć żadnej wskazówki w oficjalnej dokumentacji .

Bardzo chciałbym uzyskać pomysły, jak pomóc moim uczniom zapamiętać tę składnię. Wiedza o tym, co oznacza (lub może oznaczać) „P”, byłaby przydatna.

Eric O Lebigot
źródło
8
Poznacza Placeholder.
kev
1
@kev: wydaje się, że to powinna być odpowiedź?
ninjagecko
3
Ponieważ domysły są właściwe, przypuszczam, że Ken Thompson jest sympatykiem hipisa, a „P” oznacza „Patchouli”.
aaronasterling
2
To pytanie zostało dodane do często zadawanych pytań dotyczących wyrażeń regularnych przepełnienia stosu w sekcji „Grupy”.
aliteralmind
6
Nawiasem mówiąc, jeśli użyjesz match.groups(z s), po cichu dostaniesz krotkę wszystkich grup -_- groups('name')=> ('John', '123456')kiedy to, czego tak naprawdę chciałeś, było group('name')=> 'John' Mam nadzieję, że to zaoszczędzi kogoś gdzieś przez jakiś czas (y).
szmoore

Odpowiedzi:

262

Ponieważ wszyscy zgadujemy, równie dobrze mogę podać moje: zawsze myślałem, że oznacza Python. To może brzmieć dość głupio - co, P dla Pythona ?! - ale na swoją obronę niejasno zapamiętałem ten wątek [podkreślenie moje]:

Temat: Zgłaszanie (? P ...) rozszerzeń składni wyrażeń regularnych

Od: Guido van Rossum (gui ... @ CNRI.Reston.Va.US)

Data: 10 grudnia 1997 15:36:19

Mam nietypową prośbę do programistów Perla (tych, którzy rozwijają język Perl). Mam nadzieję, że ta lista (perl5-porters) jest właściwa. Cc'ing Python string-sig, ponieważ jest źródłem większości prac, które tutaj omawiam.

Prawdopodobnie znasz język Python. Jestem twórcą Pythona; Planuję wypuścić kolejną "główną" wersję, Python 1.5, do końca tego roku. Mam nadzieję, że Python i Perl mogą współistnieć w nadchodzących latach; zapylenie krzyżowe może być dobre dla obu języków. (Myślę, że Larry dobrze przyjrzał się Pythonowi, dodając obiekty do Perla 5; O'Reilly publikuje książki o obu językach).

Jak być może wiesz, Python 1.5 dodaje nowy moduł wyrażeń regularnych, który bardziej pasuje do składni Perla. Staraliśmy się być jak najbliżej składni Perla w składni Pythona. Jednak składnia wyrażeń regularnych ma pewne rozszerzenia specyficzne dla Pythona, z których wszystkie zaczynają się od (? P. Obecnie są dwa z nich:

(?P<foo>...)Podobny do zwykłych nawiasów grupujących, ale tekst
dopasowany przez grupę jest dostępny po zakończeniu dopasowania, poprzez symboliczną nazwę grupy „foo”.

(?P=foo)Dopasowuje ten sam ciąg, który został dopasowany przez grupę o nazwie „foo”. Odpowiednik \ 1, \ 2 itd. Z tym wyjątkiem, że do grupy odnosi
się nazwa, a nie numer.

Mam nadzieję, że to rozszerzenie specyficzne dla Pythona nie będzie kolidować z żadnymi przyszłymi rozszerzeniami Perla do składni wyrażeń regularnych Perl. Jeśli planujesz używać (? P, daj nam znać tak szybko, jak to możliwe, abyśmy mogli rozwiązać konflikt. W przeciwnym razie byłoby dobrze, gdyby składnia (? P mogła być na stałe zarezerwowana dla rozszerzeń składni specyficznych dla języka Python). (Czy jest jakiś rejestr rozszerzeń?)

na co Larry Wall odpowiedział:

[...] Na razie nie ma rejestru - twoje jest pierwsze żądanie od zewnętrznych portierów perl5, więc jest to dość niska aktywność. (Przepraszam, że w zeszłym tygodniu było jeszcze niżej - byłem w Nowym Jorku na Internet World.)

W każdym razie, jeśli o mnie chodzi, z pewnością możesz mieć „P” z moim błogosławieństwem. (Oczywiście Perl nie potrzebuje w tym momencie „P”. :-) [...]

Nie wiem więc, czym był motywowany pierwotny wybór P - wzór? symbol zastępczy? pingwiny? - ale możesz zrozumieć, dlaczego zawsze kojarzyłem go z Pythonem. Biorąc pod uwagę to, że (1) nie lubię wyrażeń regularnych i unikam ich, gdy tylko jest to możliwe, oraz (2) ten wątek wydarzył się piętnaście lat temu, jest trochę dziwny.

DSM
źródło
4
Może "rozszerzenie specyficzne dla Pythona"?
jmort253
50
Wow, znalazłeś tutaj dobre i odpowiednie dane historyczne! Moja interpretacja posta Guido jest taka, że ​​„P” oznacza „rozszerzenia specyficzne dla Pythona”.
Eric O Lebigot
1
Tak, to wydaje mi się ostateczne. To ironia losu, że Perl i PCRE początkowo skopiowały składnię tylko dlatego, że Python był pierwszym wariantem obsługującym nazwane przechwytywania. Ale obsługują też (?<group_name>…)składnię, która wydaje się być najpopularniejsza - obsługuje ją nawet Java.
Alan Moore
3
+1 To jedna z najlepszych niezręcznych odpowiedzi, której dobrze się bronisz :). Na początku myślałem, że to zbyt głupie. Ale w końcu całkowicie się zgodziłem.
Sumudu
4
Podoba mi się, że nawet twórca Pythona używa dziwacznej, tajemnej składni, gdy w grę wchodzi Perl, a społeczność Perla jest z tym w porządku. Jeśli spróbujesz dodać rozszerzenia / składnię specyficzne dla Perla do Pythona, na ulicach pojawiłaby się krew.
Keith Ripley
20

Wzór! Grupa nazywa (pod) wzorzec do późniejszego użycia w wyrażeniu regularnym. Zobacz dokumentację tutaj, aby uzyskać szczegółowe informacje na temat wykorzystania takich grup.

Mikrofon
źródło
3
+1: To jest dobre urządzenie mnemoniczne: (?P<name>…)to „wzorzec name”. Jednak wszystko jest wzorcem w wyrażeniu regularnym, więc dziwne jest oznaczanie (?P<…>…)grup tylko wzorcami. To jednak wystarczy dla moich uczniów. :)
Eric O Lebigot
1
@EOL nie uczy studentów fałszywych rzeczy. Są trudniejsze do zniszczenia, gdy sięgasz po dokładność, niż myślisz. Na przykład. niektóre, jak dla mnie, zajmują wiele lat 5. Paradoksalnie zachęca się do swobodnego mówienia, po prostu zawsze mów o tym bardzo jasno i wyraźnie - np. Opowiedz uczniom cały swój poprzedni komentarz (poprawiając być może ostatnie zdanie;).)
n611x007
5

Rozszerzenie Pythona. Z Python Docos:

Rozwiązaniem wybranym przez programistów Perla było użycie (? ...) jako składni rozszerzenia. ? zaraz po nawiasie wystąpił błąd składniowy, ponieważ znak? nie miałoby nic do powtórzenia, więc nie powodowało to żadnych problemów ze zgodnością. Znaki bezpośrednio po? wskazują, jakie rozszerzenie jest używane, więc (? = foo) to jedna rzecz (pozytywne potwierdzenie wyprzedzające), a (?: foo) to coś innego (nieprzechwytywana grupa zawierająca podwyrażenie foo).

Python obsługuje kilka rozszerzeń Perla i dodaje składnię rozszerzenia do składni rozszerzenia Perla. Jeśli pierwszym znakiem po znaku zapytania jest P, wiesz, że jest to rozszerzenie specyficzne dla Pythona

https://docs.python.org/3/howto/regex.html

Jakiś facet
źródło
Dobrze zauważony! Potwierdza to odczucie DSM.
Eric O Lebigot