<?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-04-18T15:56:29Z</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 ''egrep'' (lub ''grep -E'' - 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 ''egrep'' (lub ''grep -E'' - 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. ''69'' jako odrębne słowo zdecydowanie wygląda na liczbę, natomiast ''Hoza69'' 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. ''1.'' i ''.1'' są poprawnymi zapisami liczb zmiennoprzecinkowych.&lt;br /&gt;
# podaj wzorzec dla zapisu czasu w postaci ''HH:MM'', 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 ''dd-mm-rrrr'', 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 '[^[:blank:]]' ...&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 ''egrep'' używając opcji:&lt;br /&gt;
#:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;egrep -v '^[[:blank:]]*$' ...&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#:'''Uwaga:''' ''egrep'' niestety nie interpretuje standardowych sekwencji np. '''\t''' jako oznaczającej kod tabulacji, itd. Na szczęście w Pythonie one działają.&lt;br /&gt;
# z strumienia rekordów mapy ''passwd'' 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 ''konwencja'', że piąte pole (opisowe, określane też nazwą ''GECOS'') powinno zawierać ''Imie Drugieimie Nazwisko'' 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 ''passwd'' nie spełnia tej konwencji, oraz ile z nich ma foldery domowe poza katalogiem mającym ''public'' 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 ''passwd''). 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 '^[a-z]{2}[0-9]{6}:' | wc -l&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#:natomiast aby policzyć te, które ''ponadto'' mają foldery domowe poza katalogiem ''public'':&lt;br /&gt;
#:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;egrep -v '^[a-z]{2}[0-9]{6}:' |egrep -v '^([^:]*:){5}[^:]*/public/'&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 ''egrep''-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. '''Proszę napisać program znajdujący wszystkie palindromy w pliku słów i nie korzystający z wyrażeń regularnych.'''&lt;br /&gt;
#: W Linuxie listę słów można zazwyczaj znaleźć w folderze ''/usr/share/dict'', 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 ''x'', 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 ''/usr/share/dict/words'' na moim komputerze wszystkie słowa pasujące do tego wzorca zaczynają się na literę '''e''' -- jest ich nie tak mało, bo 91.&lt;br /&gt;
&lt;br /&gt;
Ad. palindromy:&lt;br /&gt;
*wersja ''simple''&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 ''sophisticated''&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 '''każdy''' 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>