Historia wymaga pasterzy, nie rzeźników.


W tabeli 2.1 przedstawiono dozwolone argumenty.
W tabeli 2.2 zaprezentowano, co robią te argumenty.
Powinienem również krótko wspomnieć o nieco nietypo-wej opcji sprintf — możliwości użycia notacji pozycyjnej ( pozycja)$ w celu uzyskania dostępu do określonego 41
Zastępowanie podłańcuchów znaków za pomocą sprintf 2Ł
ZIA
Tabela 2.1. Kody sprintf dla łańcuchów znaków ZD
Argument
Dozwolony Wyjaśnienie
O
łańcucha znaków argument
R
c
*, -
Oczekuje obiektu klasy
Fixnum reprezentującego
kod znaku.
s
*,
Oczekuje obiektu klasy
String.
p
*,
Dowolny obiekt
W
odpowiadający na metodę
Ó
.inspect().
AKNI Z
Tabela 2.2. Argumenty sprintf dla łańcuchów znaków HAM
Argument
Wyjaśnienie
CUC
*d
d musi być liczbą całkowitą. Określa szerokość pola.
ŁAŃ
-
Wyrównanie do lewej.
wpisu w podanej tablicy. Nieco denerwujące jest jednak PRACA Z
to, że notacja ta rozpoczyna odliczanie od 1, a nie od 0
(tak jak w przypadku obiektów klasy Array).
'Witaj, %1$s! Dzisiaj kończysz %2$d lat! Wszystkiego
¦najlepszego, %1$s!' % ['Amadeusz', 13]
#=> "Witaj, Amadeusz! Dzisiaj kończysz 13 lat!
¦Wszystkiego najlepszego, Amadeusz!"
42
R
Zastępowanie podłańcuchów znaków za pomocą wyrażeń regularnych OZD
ZIA
Zastępowanie podłańcuchów
Ł
znaków za pomocą wyrażeń
2
regularnych
'W tej chwili jest:
¦12:34:21'.sub(/(\d\d):(\d\d):(\d\d)/, '\1\2\3')
#=> "W tej chwili jest: 123421"
PRACA Z
I znów wyrażenia regularne mogą nam się bardzo przydać.
By dokonać interpolacji wyników dopasowania z grup w nawiasach, należy użyć \1 do \9. By zastąpić wszystkie wystąpienia w łańcuchu znaków, należy użyć .gsub za-
ŁAŃ
miast .sub.
CUC
W powyższym przykładzie całe wyrażenie 12:34:21 zo-HAM
stało dopasowane i zastąpione podgrupami od 1 do 3 bez I Z
rozdzielających je dwukropków. Alternatywnie można rów-N
nież po prostu zastąpić każde wystąpienie znaku : poja-AK
wiające się między cyframi.
ÓW
Można by to było zapisać w następujący sposób:
'W tej chwili jest: 12:34:21'.gsub(/(\d):
¦(\d)/, '\1\2')
#=> "W tej chwili jest: 123421"
43
Praca z Unicode

ZIA
Praca z Unicode
ZDO
#!/usr/bin/ruby -wKu
R
'
'.scan(/./) { |b| print b, ' ' }
Zwraca:
Ruby przyjmuje pliki źródłowe z kodowaniem UTF-8.
W
W celu upewnienia się, że wszystko będzie poprawnie Ó
interpretowane w innych systemach operacyjnych oraz AKN
przy innych ustawieniach regionalnych, należy dodać I Z
opcję wiersza poleceń -Ku do wiersza shebang1. Zmody-fikowany wiersz shebang to pierwszy wiersz powyższego HAM
fragmentu kodu.
CUC
Sam Ruby nie jest w pełni zinternacjonalizowany. Ruby nie ŁAŃ
jest na przykład świadomy wielobajtowej natury UTF-8
poza pierwszymi 255 kodami znaków. Z tego powodu,
gdy mamy do czynienia z umiędzynarodowionymi łań-
PRACA Z
cuchami znaków, z metody #each_byte należy korzystać z rozwagą. Nie będzie ona na przykład działała na języ-kach niełacińskich.
puts "
" # dane wyjściowe bezpośrednio do bufora
"
".each_byte { |b| print(""<1 Wiersz shebang to inaczej pierwszy wiersz programu rozpoczynający się od znaków #! i wskazujący powłoce systemów *nix, jakiego interpretera należy użyć do wykonania poleceń programu — przyp. tłum.
44
R
Oczyszczanie danych wejściowych
OZD
ZIA
Zwraca:
Ł 2
? ? ? ? ? ?
By przejść takie znaki, należy zamiast tego skorzystać z wyrażeń regularnych (działają one w UTF-8). Kod
umożliwiający to znajduje się na początku podrozdziału.
Kiedy pracuje się z Unicode, do tworzenia wycinków oraz PRACA Z
dopasowywania należy wykorzystać wyrażenia regular-ne. Poza tym wyjątkiem, łańcuchy znaków z zawartością o kodowaniu Unicode powinny się zachować dokładnie zgodnie z oczekiwaniami.
ŁAŃCUC
H
Oczyszczanie danych
AM
I Z
wejściowych
NAK
new_password = gets
Ó
if new_password.count '^A-Za-z._' != 0 then
W
puts "Złe hasło"
else
# zrób coś jak w podrozdziale "Szyfrowanie łańcucha znaków"
end
Powiedzmy, że chcemy napisać program zmieniający hasła przeznaczony dla systemu *nix (być może korzystający z serwera LDAP). Po ukazaniu się prośby o zalogowanie się, w haśle można użyć prawie każdego znaku, jaki da się wygenerować na klawiaturze. Kilka znaków, których nie można użyć, może jednak przyprawić użytkowników o ból głowy, kiedy odkryją, że po zmianie hasła nie po-45
Praca z końcami wierszy

ZIA
trafią się już zalogować. By ułatwić sobie życie, możemy napisać program zmieniający hasła, który ograniczy ha-ZDO
sło do znaków alfanumerycznych i kilku im podobnych.
R
Metoda String#count, zastosowana jak powyżej, może nam w tym pomóc.
Rozwiązanie to działa dzięki użyciu specjalnej składni współdzielonej przez .count, .tr, delete oraz squeeze.
Parametr zaczynający się od znaku ^ powoduje negację W
listy. Lista składa się z dowolnych poprawnych znaków Ó
w bieżącym zbiorze znaków i może zawierać zakresy
AKN
utworzone za pomocą znaku -. Jeśli do funkcji tych I Z
przekazana zostanie więcej niż jedna lista, wykorzystuje się część wspólną list znaków zgodnie z logiką zbiorów HAM
— co oznacza, że w filtrowaniu użyte zostaną jedynie CUC
znaki występujące w obu listach.
ŁAŃ
W przypadku innego rodzaju działań oczyszczających można po prostu zastąpić wszystkie niewłaściwe znaki znakiem _ (jak na przykład w formularzu CGI).
PRACA Z
evil_input = '`cat /etc/passwd`'
evil_input.tr('./\`', '_')
#=> "_cat _etc_passwd_"
Praca z końcami wierszy
Kiedy mamy do czynienia z tekstem z trzech głównych systemów operacyjnych, możemy się spotkać z najstar-szym chyba sposobem dzielenia plików (tabela 2.3).
46
R
Praca z końcami wierszy
OZD
ZIA
Tabela 2.3. Zakończenia wiersza specyficzne dla systemów operacyjnych
Ł 2
System operacyjny
Zakończenie wiersza
Mac OS 9 i starsze wersje
\r
Windows
\r\n
*nix
\n
Jeśli pracujemy z tekstem w systemach Windows oraz *nix, prawdopodobnie nie musimy się nad tym zastanawiać —
PRACA Z
są one obsługiwane w niemalże ten sam sposób.
"a\r\nb\r\nc\r\n".each_line { |line|
puts(line.inspect)
ŁA
}
ŃCUC
Zwraca:
"a\r\n"
H
"b\r\n"
AM
"c\r\n"
I Z
"a\r\nb\r\nc\r\n".each_line { |line|
NAK
puts(line.chomp.inspect) # chomp bezpiecznie usuwa oba
}
ÓW
Zwraca:
"a"
"b"
"c"
W systemie Linux wygląda to prawie identycznie.
"a\nb\nc\n".each_line { |line|
puts(line.inspect)
}
Zwraca:
"a\n"
47
Przetwarzanie dużych łańcuchów znaków 2Ł
ZIA
"b\n"
"c\n"
ZDO
Dla plików systemu Mac OS konieczne jest określenie R
separatora.
"a\rb\rc\r".each_line "\r" { |line|
puts(line.inspect)
}
Zwraca:
"a\r"

"b\r"
"c\r"
AKNI Z Przetwarzanie dużych
HAM
łańcuchów znaków
CUC
ŁAŃ
my_string = ''