Zanurkuj w Pythonie/Analiza przypadku: Przetwarzanie numerów telefonów: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Linia 99:
>>>
 
# Wzorzec w tym przykładzie jest taki sam jak w poprzednim, z wyjątkiem, że teraz na początku łańcucha dopasowujemy \D* przed pierwszą zapamiętywaną grupą (numerem kierunkowym). Zauważ że tych znaków nie zapamiętujemy tych znaków (nie są one w nawiasie). Jeśli je napotkamy, to ignorujemy je i przechodzimy do numeru kierunkowego.
# This is the same as in the previous example, except now you're matching \D*, zero or more non-numeric characters, before the first remembered group (the area code). Notice that you're not remembering these non-numeric characters (they're not in parentheses). If you find them, you'll just skip over them and then start remembering the area code whenever you get to it.
# Teraz udało się przetworzyć numer telefonu z nawiasem otwierającym na początku. (Zamykający był już wcześniej obsługiwany; był traktowany jako nienumeryczny znak pasujący do teraz drugiego \D*.)
# You can successfully parse the phone number, even with the leading left parenthesis before the area code. (The right parenthesis after the area code is already handled; it's treated as a non-numeric separator and matched by the \D* after the first remembered group.)
# Tak na wszelki wypadek sprawdzamy czy nie popsuliśmy czegoś. Jako, że początkowy znak jest całkowicie opcjonalny, następuje dopasowanie w dokładnie taki sam sposób jak w poprzednim przykładzie.
# Just a sanity check to make sure you haven't broken anything that used to work. Since the leading characters are entirely optional, this matches the beginning of the string, then zero non-numeric characters, then a remembered group of three digits (800), then one non-numeric character (the hyphen), then a remembered group of three digits (555), then one non-numeric character (the hyphen), then a remembered group of four digits (1212), then zero non-numeric characters, then a remembered group of zero digits, then the end of the string.
# W tym miejscu wyrażenia regularne sprawiają, że chce sie człowiekowi rozbić bardzo dużym młotem monitor. Dlaczego to nie pasuje? Wszystko za sprawą 1 przed numerem kierunkowym (numer kierunkowy USA), a przecież przyjęliśmy, że na początku mogą być tylko nienumeryczne znaki. Ech...
# This is where regular expressions make me want to gouge my eyes out with a blunt object. Why doesn't this phone number match? Because there's a 1 before the area code, but you assumed that all the leading characters before the area code were non-numeric characters (\D*). Aargh.
 
Cofnijmy się na chwilę. Jak narazie wszystkie wyrażenia dopasowywaliśmy od początku łańcucha. Ale teraz widać wyraźnie, że na początku naszego łańcucha mamy nieokreśloną liczbę znaków których kompletnie nie potrzebujemy. Po co mamy więc dopasowywać początek łańcucha? Jeśli tego nie zrobimy, to przecież pominie on tyle znaków ile mu się uda, a przecież o to nam chodzi. Takie podejście prezentuje następny przykład.
Let's back up for a second. So far the regular expressions have all matched from the beginning of the string. But now you see that there may be an indeterminate amount of stuff at the beginning of the string that you want to ignore. Rather than trying to match it all just so you can skip over it, let's take a different approach: don't explicitly match the beginning of the string at all. This approach is shown in the next example.
 
'''Przykład 7.15. Numerze telefonu, znajdę cię gdziekolwiek jesteś!'''
Linia 116:
('800', '555', '1212', '1234')
 
# Zauważ, że brakuje ^ w tym wyrażeniu regularnym, Teraz już nie dopasowujemy początku łańcucha, bo przecież nikt nie powiedział, że wyrażenie musi pasować do całego łańcucha a nie do fragmentu. Mechanizm wyrażeń regularnych sam zadba o namierzenie miejsca do którego ono pasuje (o ile w ogóle).
# Note the lack of ^ in this regular expression. You are not matching the beginning of the string anymore. There's nothing that says you need to match the entire input with your regular expression. The regular expression engine will do the hard work of figuring out where the input string starts to match, and go from there.
# Teraz nareszcie pasuje numer ze znakami na początku (w tym cyframi) i dowolnymi, jakimikolwiek separatorami w środku.
# Now you can successfully parse a phone number that includes leading characters and a leading digit, plus any number of any kind of separators around each part of the phone number.
# Na wszelki wypadek sprawdzamy i to. Działa!
# Sanity check. this still works.
# ThatTo stillteż works toodziała.
 
Widzisz jak szybko wyrażenia regularne wymykają się spod kontroli? Rzuć okiem na jedną z poprzednich iteracji. Widzisz różnice pomiędzy nią i następną?
See how quickly a regular expression can get out of control? Take a quick glance at any of the previous iterations. Can you tell the difference between one and the next?
 
Póki jeszcze rozumiemy to co napisaliśmy, rozpiszmy to jako rozwlekłe wyrażenie regularne żeby nie zapomnieć co jest co i dlaczego.
While you still understand the final answer (and it is the final answer; if you've discovered a case it doesn't handle, I don't want to know about it), let's write it out as a verbose regular expression, before you forget why you made the choices you made.
 
'''Przykład 7.16. Przetwarzanie numerów telefonu (wersja finalna)'''
 
<nowiki>>>> phonePattern = re.compile(r'''
# don'tnie matchdopasowuj beginningpoczątku of stringłańcucha, numbernumer może cansię startzacząć anywheregdziekolwiek
(\d{3}) # areanumer codekierunkowy is- 3 digitscyfry (e.gnp. '800')
\D* # optionalopcjonalny nienumeryczny separator is any number of non-digits
(\d{3}) # trunkpierwsza isczęść numeru - 3 digitscyfry (e.gnp. '555')
\D* # optionalopcjonalny separator
(\d{4}) # restdruga ofczęść number is 4 digitsnumeru (e.gnp. '1212')
\D* # optionalopcjonalny separator
(\d*) # extensionnumer iswewnętrzny optionaljest andopcjonalny cani bemoże anymieć numberdowolną of digitsdługość
$ # endkoniec of stringłańcucha
''', re.VERBOSE)
>>> phonePattern.search('work 1-(800) 555.1212 #1234').groups() #(1)
Linia 143:
('800', '555', '1212', '')</nowiki>
 
# Pomijając fakt, że jest ono podzielone na wiele linii, to wyrażenie jest dokładnie takie samo jak po ostatnim kroku, więc nie jest niespodzianką, że dalej działa jak powinno
# Other than being spread out over multiple lines, this is exactly the same regular expression as the last step, so it's no surprise that it parses the same inputs.
# Jeszcze jedna próba. Tak, działa! Skończone!
# Final sanity check. Yes, this still works. You're done.
 
 
<noinclude>