<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=%2FCw5</id>
	<title>/Cw5 - Historia wersji</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=%2FCw5"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=/Cw5&amp;action=history"/>
	<updated>2026-10-27T23:17:52Z</updated>
	<subtitle>Historia wersji tej strony wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=/Cw5&amp;diff=2045&amp;oldid=prev</id>
		<title>Jarekz: Utworzono nową stronę &quot;= TI:WTBD/Ćwiczenia 5 =  Konstruujemy przykładowe wyrażenia regularne.  Przykłady uruchamiamy/sprawdzamy za pomocą polecenia &#039;&#039;egrep&#039;&#039; (lub &#039;&#039;grep -E&#039;&#039; - na jed...&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=/Cw5&amp;diff=2045&amp;oldid=prev"/>
		<updated>2015-05-23T14:58:27Z</updated>

		<summary type="html">&lt;p&gt;Utworzono nową stronę &amp;quot;= &lt;a href=&quot;/edu/index.php/TI:WTBD&quot; title=&quot;TI:WTBD&quot;&gt;TI:WTBD&lt;/a&gt;/Ćwiczenia 5 =  Konstruujemy przykładowe wyrażenia regularne.  Przykłady uruchamiamy/sprawdzamy za pomocą polecenia &amp;#039;&amp;#039;egrep&amp;#039;&amp;#039; (lub &amp;#039;&amp;#039;grep -E&amp;#039;&amp;#039; - na jed...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nowa strona&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= [[TI:WTBD]]/Ćwiczenia 5 =&lt;br /&gt;
&lt;br /&gt;
Konstruujemy przykładowe wyrażenia regularne.&lt;br /&gt;
&lt;br /&gt;
Przykłady uruchamiamy/sprawdzamy za pomocą polecenia &amp;#039;&amp;#039;egrep&amp;#039;&amp;#039; (lub &amp;#039;&amp;#039;grep -E&amp;#039;&amp;#039; - na jedno wychodzi).&lt;br /&gt;
&lt;br /&gt;
Częstą trudnością w konstrukcji wyrażeń regularnych w praktyce jest uwzględnienie kontekstu, w jakim szukane napisy mogą się pojawiać -- tj. tego, jak je wyodrębnić z ,,tła&amp;quot;. Tutaj na razie pomińmy tę trudność, która ma znaczenie dla paru pierwszych przykładów: np. &amp;#039;&amp;#039;69&amp;#039;&amp;#039; jako odrębne słowo zdecydowanie wygląda na liczbę, natomiast &amp;#039;&amp;#039;Hoza69&amp;#039;&amp;#039; jest legalnym identyfikatorem w Pythonie, i w kodzie może pełnić rolę nazwy zmiennej lub klasy itp.&lt;br /&gt;
&lt;br /&gt;
# podaj wzorzec dla zapisu liczby całkowitej lub zmiennoprzecinkowej (bez wykładnika)&lt;br /&gt;
#: To nie jest takie bardzo proste. Kierujmy się postacią zapisu literalnych liczb w Pythonie: np. &amp;#039;&amp;#039;1.&amp;#039;&amp;#039; i &amp;#039;&amp;#039;.1&amp;#039;&amp;#039; są poprawnymi zapisami liczb zmiennoprzecinkowych.&lt;br /&gt;
# podaj wzorzec dla zapisu czasu w postaci &amp;#039;&amp;#039;HH:MM&amp;#039;&amp;#039;, tzn. od 00:00 do 23:59 -- ma nie akceptować niepoprawnych godzin, takich jak 25:63&lt;br /&gt;
#:&amp;lt;code&amp;gt;^([01][0-9]|2[0-3]):[0-5][0-9]$&amp;lt;/code&amp;gt;&lt;br /&gt;
# podaj wzorzec dla zapisu daty w postaci &amp;#039;&amp;#039;dd-mm-rrrr&amp;#039;&amp;#039;, z uwzględnieniem dat z wieku 20 i 21. W pierwszym podejściu -- niech nie dopuszcza dni &amp;gt; 31 ani miesięcy &amp;gt; 12.  &lt;br /&gt;
#: Zaobserwuj, jak to się komplikuje gdy próbujesz uwzględnić różne długości miesięcy. Uwzględnienie różnicy pomiędzy latami przestępnymi a nieprzestępnymi to już zdecydowanie nie jest odpowiednie zastosowanie dla wyrażeń regularnych.&lt;br /&gt;
# w strumieniu tekstowym zlicz linijki nie zawierające znaków niepustych; wyeliminuj (pomiń) takie linijki. Znajdź dwa różne sposoby.&lt;br /&gt;
#:Można albo wyróżnić te linijki żądając, by zawierały choć jeden znak nie będący spacją albo tabulacją:&lt;br /&gt;
#:&amp;lt;code&amp;gt;egrep &amp;#039;[^[:blank:]]&amp;#039; ...&amp;lt;/code&amp;gt;&lt;br /&gt;
#:albo użyć wyrażenia, do którego pasują linijki zawierające co najwyżej same znaki puste, i odwrócić działanie &amp;#039;&amp;#039;egrep&amp;#039;&amp;#039; używając opcji:&lt;br /&gt;
#:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;egrep -v &amp;#039;^[[:blank:]]*$&amp;#039; ...&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#:&amp;#039;&amp;#039;&amp;#039;Uwaga:&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;egrep&amp;#039;&amp;#039; niestety nie interpretuje standardowych sekwencji np. &amp;#039;&amp;#039;&amp;#039;\t&amp;#039;&amp;#039;&amp;#039; jako oznaczającej kod tabulacji, itd. Na szczęście w Pythonie one działają.&lt;br /&gt;
# z strumienia rekordów mapy &amp;#039;&amp;#039;passwd&amp;#039;&amp;#039; wyodrębnij rekordy tych osób, w których podane jest drugie imię. Jaką część one stanowią?&lt;br /&gt;
#: Nie ma na to ścisłych reguł, ale często stosowana jest &amp;#039;&amp;#039;konwencja&amp;#039;&amp;#039;, że piąte pole (opisowe, określane też nazwą &amp;#039;&amp;#039;GECOS&amp;#039;&amp;#039;) powinno zawierać &amp;#039;&amp;#039;Imie Drugieimie Nazwisko&amp;#039;&amp;#039; właściciela konta (z tym że nie każdy ma drugie imię), i ewentualnie po przecinku jakieś informacje dodatkowe typu nr gabinetu, telefon służbowy itp. W pierwszym kroku należy odrzucić rekordy, które nie są zgodne z tym szablonem; są to najprawdopodobniej konta w jakimś sensie ,,funkcyjne&amp;quot;.&lt;br /&gt;
#:Jako wzorzec wyróżniający rekordy osób wg. powyższego kryterium można przyjąć&lt;br /&gt;
#:&amp;lt;code&amp;gt;^([^:]*:){4}[A-Z][a-z]+ ([A-Z][a-z]+ )?[A-Z][a-z]+[,:]&amp;lt;/code&amp;gt;&lt;br /&gt;
#:(zakładamy tu, że nie należy raczej się spodziewać imion czy nazwisk 1-literowych -- jeśli w miejscu na imię czy nazwisko znajduje się tylko jedna litera, to najprawdopodobniej jest ona czymś innym, i takie konto odrzucamy). Z kolei następujący wzorzec już narzuca wymaganie, by drugie imię występowało:&lt;br /&gt;
#:&amp;lt;code&amp;gt;^([^:]*:){4}[A-Z][a-z]+ [A-Z][a-z]+ [A-Z][a-z]+[,:])&amp;lt;/code&amp;gt;&lt;br /&gt;
# napisz wyrażenie regularne opisujące konwencję nazw (loginów) kont studenckich na FUW; ustalić, ile kont w &amp;#039;&amp;#039;passwd&amp;#039;&amp;#039; nie spełnia tej konwencji, oraz ile z nich ma foldery domowe poza katalogiem mającym &amp;#039;&amp;#039;public&amp;#039;&amp;#039; jako drugi człon ścieżki.&lt;br /&gt;
#:Konwencja o której mowa wyraża się wzorcem&lt;br /&gt;
#:&amp;lt;code&amp;gt;^[a-z]{2}[0-9]{6}$&amp;lt;/code&amp;gt;&lt;br /&gt;
#:(chodzi tu o sam login, nie o rekord &amp;#039;&amp;#039;passwd&amp;#039;&amp;#039;). Aby policzyć konta nie przestrzegające tej konwencji, należy użyć polecenia&lt;br /&gt;
#:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;egrep -v &amp;#039;^[a-z]{2}[0-9]{6}:&amp;#039; | wc -l&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#:natomiast aby policzyć te, które &amp;#039;&amp;#039;ponadto&amp;#039;&amp;#039; mają foldery domowe poza katalogiem &amp;#039;&amp;#039;public&amp;#039;&amp;#039;:&lt;br /&gt;
#:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;egrep -v &amp;#039;^[a-z]{2}[0-9]{6}:&amp;#039; |egrep -v &amp;#039;^([^:]*:){5}[^:]*/public/&amp;#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
# w liście słów angielskich znajdź wszystkie palindromy 6-literowe i 7-literowe&lt;br /&gt;
#:6-literowe: &amp;lt;code&amp;gt;^(.)(.)(.)\3\2\1$&amp;lt;/code&amp;gt;&lt;br /&gt;
#:7-literowe: &amp;lt;code&amp;gt;^(.)(.)(.).\3\2\1$&amp;lt;/code&amp;gt;&lt;br /&gt;
#:Zauważmy, że nie ma sposobu, by za pomocą wyrażenia regularnego zapisać warunek, że napis jest palindromem (niezależnie od jego długości). Co gorsza, wzorce &amp;#039;&amp;#039;egrep&amp;#039;&amp;#039;-a dopuszczają tylko do dziewięciu referencji wstecznych (w Pythonie -- do 99). Natomiast bez korzystania z wyrażeń regularnych bardzo łatwo jest napisać program poszukujący palindromów. &amp;#039;&amp;#039;&amp;#039;Proszę napisać program znajdujący wszystkie palindromy w pliku słów i nie korzystający z wyrażeń regularnych.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
#: W Linuxie listę słów można zazwyczaj znaleźć w folderze &amp;#039;&amp;#039;/usr/share/dict&amp;#039;&amp;#039;, może tam być parę list odpowiadających różnym językom.&lt;br /&gt;
# w liście słów angielskich znajdź wszystkie takie, gdzie druga litera to &amp;#039;&amp;#039;x&amp;#039;&amp;#039;, a ostatnia i pierwsza są takie same.&lt;br /&gt;
#:&amp;lt;code&amp;gt;^(.)x.*\1$&amp;lt;/code&amp;gt;&lt;br /&gt;
#:Ciekawe, że w pliku &amp;#039;&amp;#039;/usr/share/dict/words&amp;#039;&amp;#039; na moim komputerze wszystkie słowa pasujące do tego wzorca zaczynają się na literę &amp;#039;&amp;#039;&amp;#039;e&amp;#039;&amp;#039;&amp;#039; -- jest ich nie tak mało, bo 91.&lt;br /&gt;
&lt;br /&gt;
Ad. palindromy:&lt;br /&gt;
*wersja &amp;#039;&amp;#039;simple&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
&lt;br /&gt;
for name in argv[1:]:&lt;br /&gt;
    for line in open(name):&lt;br /&gt;
        word = line.strip()&lt;br /&gt;
        if len(word) &amp;gt; 2 and word == word[::-1]:&lt;br /&gt;
            print word&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*wersja &amp;#039;&amp;#039;sophisticated&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
from sys import argv&lt;br /&gt;
from itertools import chain&lt;br /&gt;
&lt;br /&gt;
files = (open(name) for name in argv[1:])&lt;br /&gt;
lines = chain.from_iterable(files)&lt;br /&gt;
words = (l.strip() for l in lines)&lt;br /&gt;
palindromes = (word for word in words &lt;br /&gt;
                   if len(word) &amp;gt; 2 and word == word[::-1])&lt;br /&gt;
&lt;br /&gt;
for w in palindromes: print w&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Żądanie, by palindrom miał długość co najmniej 3 jest dość arbitralne. Zauważmy jednak, że &amp;#039;&amp;#039;&amp;#039;każdy&amp;#039;&amp;#039;&amp;#039; wyraz 1-literowy jest palindromem, a każdy palindrom 2-literowy składa się z 2 identycznych liter -- są więc ,,mało interesujące&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Jarekz</name></author>
		
	</entry>
</feed>