Archiwum kategorii ‘Programowanie‘

 
 

5 praktycznych wyrażen regularnych w PHP

Za każdym razem gdy przychodzi mi skorzystać z dobrodziejstwa jakim są wyrażenia regularne (które swoją drogą mogłyby się dorobić jakiegoś ogólnie uznawanego standardu), sięgam po gotowe i sprawdzone wzorce. Poniżej umieściłem kilka najczęściej używanych przeze mnie wyrażeń regularnych wraz z przykładowym kodem w PHP.

Adres email
Walidacja adresu email jest często spotykanym przykładem użycia wyrażeń regularnych. Adres email składa się z 3 podstawowych części:

  • nazwy użytkownika - za sprawdzenie tego elementu odpowiada ([0-9a-zA-Z]([-_.\w]*[0-9a-zA-Z_])*
  • symbolu @
  • oraz nazwy domeny - za sprawdzenie tego elementu odpowiada (([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})

Całość daje nam razem uproszczony adres email, którego poprawność możemy sprawdzić używając poniższego kodu:

$test_string = "przykladowy@email.tutaj.pl";
if (preg_match('/^([0-9a-zA-Z]([-_.\w]*[0-9a-zA-Z_])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})$/', $test_string))
{
	echo 'OK';
}
else
{
	echo 'Failed';
}

Adres URL
Czyli format adresowania zasobów internetowych najczęściej kojarzony z adresami stron www. Adres ten możemy rozbić na następujące części:

  • rodzaj protokołu - (http|https|file)
  • opcjonalna nazwa użytkownika i hasło - (\w*:\w*@)?
  • nazwa hosta - [-\w.]+
  • opcjonalny numer portu - (:\d+)?
  • ścieżka dostępu - (/([\w/_.]*
  • zapytanie - (\?\S+)?

Poprawność URLa możemy sprawdza następujący kawałek kodu:

$test_string = "http://login:haslo@www.rogozinski.net:80/admin/test.php?action=edit&id=166";
if (preg_match("/^(http|https|file):\/\/(\w*:\w*@)?[-\w.]+(:\d+)?(\/([\w\-\.\/]*(\?\S+)?)?)?$/", $test_string))
{
	echo 'OK';
}
else
{
	echo 'Failed';
}

Adres IP

W wydaniu IPv4, są to cztery liczby od 0 do 255 oddzielone kropkami.

$test_string = "255.255.255.0";
if preg_match('/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/', $test_string))
{
	echo 'OK';
}
else
{
	echo 'Failed';
}

Data i godzina (w formacie 24H)

$string = '2007-02-15 03:15';
if (preg_match('/^([0-9]{4}-[0-9]{2}-[0-9]{2})\s((0{0,1}[0-9])|(1[0-9])|([2][0-4])):([0-5][0-9])$/', $string))
{
	echo 'OK';
}
else
{
	echo 'Failed';
}

Kod pocztowy

$test_string = '05-324';
if (preg_match('/^[0-9]{2}[-]([0-9]{3})?$/', $test_string))
{
	echo 'OK';
}
else
{
	echo 'Failed';
}

Wszystkie przykłady wyświetlają napis ‘OK’ w razie prawidłowego rozpoznania wzorca i ‘Failed’ w razie porażki.

Warto zobaczyć:

Odległość Levenshteina przy porównywaniu ciągów znaków

Zwykłe porównywanie stringów czy to w php czy asp, sprowadza się do porównywania napisów znak po znaku i wyniku w postaci true lub false. Czasami jednak potrzebujemy porównać napisy powołując się nie na ich bezpośrednią równość, ale na ich podobieństwo.

Jednym z prostszych algorytmów, który pozwoli nam na zbadanie podobieństwa dwóch ciągów znaków jest algorytm Levenshteina, określający tzw. odległość Levenshteina.

Algorytm w oparciu o zdefiniowane wcześniej operacje proste (np. wstawienie znaku, usunięcie znaku, zmiana znaku na inny) określa najmniejszą liczbę operacji, potrzebnych do transformacji pierwszego napisu w drugi. Łatwo sobie wyobrazić, że dla identycznych napisów odległość Levenshteina będzie równa 0, natomiast dla dwóch całkowicie różnych napisów, będzie równa liczbie znaków dłuższego z ciągów. Krótko mówiąc im mniejsza odległość, tym napisy są bardziej do siebie podobne.

Algorytm ten można modyfikować dodając np. nowe operacje, lub przypisując operacjom wagi.

Warto zauważyć, że PHP dostarcza nam własną implementację algorytmu Levenshteina, możemy jej użyć wywołując funkcję levenshtein.

int levenshtein ( string $str1, string $str2 [, int $cost_ins, int $cost_rep, int $cost_del] )

Natomiast w C# porównywaniem string’ów musimy się zająć sami. Przykładowa implementacja może wyglądać na przykład tak:

public static int LevenshteinDistance(String s1, String s2)
{
	const int cost_ins = 1;
	const int cost_del = 1;
	const int cost_sub = 1;
 
	int n1 = s1.Length;
	int n2 = s2.Length;
 
	int[] p = new int[n2+1];
	int[] q = new int[n2+1];
	int[] r;
 
	p[0] = 0;
	for( int j = 1; j <= n2; ++j )
	{
		p[j] = p[j-1] + cost_ins;
	}
 
	for( int i = 1; i <= n1; ++i )
	{
		q[0] = p[0] + cost_del;
		for( int j = 1; j <= n2; ++j )
		{
			int d_del = p[j] + cost_del;
			int d_ins = q[j - 1] + cost_ins;
			int d_sub = p[j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : cost_sub);
			q[j] = Math.Min( Math.Min( d_del, d_ins ), d_sub );
		}
		r = p;
		p = q;
		q = r;
	}
	return p[n2];
}

Wynikiem funkcji Levenshteina jest liczba całkowita. Co jednak zrobić gdy na podstawie porównania ciągów znaków chcemy je klasyfikować? Liczba całkowita nie jest w tym wypadku zbyt wymowna. Lepszym pomysłem jest uzależnienie wyniku od maksymalnej długości ciągu.

Przykład:

public static float LevenshteinTextComparison(String s1, String s2)
{
	if (s1.Equals(String.Empty) && s2.Equals(String.Empty))
	{
		return 1;
	}
	return 1 - ((float)LevenshteinDistance(s1, s2) / (float)Math.Max(s1.Length, s2.Length));
}

Teraz zamiast mało mówiącej liczby całkowitej, otrzymujemy liczbę rzeczywistą z zakresu <0, 1> określającą podobieństwo napisów. Im bliżej jedynki tym ciągi są bardziej podobne i w drugą stronę, im bliżej zera, tym ciągi bardziej się od siebie różnią.

Przydatne linki:

http://pl.wikipedia.org/wiki/Odległość_Levenshteina
http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Levenshtein_distance

Kontrolki kompozytowe w ASP.NET a ClientID

Wyprodukowałem sobie dzisiaj bardzo prostą kontrolkę kompozytową. Jej zadaniem jest pokazywanie i chowanie div’a z tekstem. Całość odbywa się tylko po stronie klienta. Normalnie (mam na myśli HTML) byłoby to banalnie proste, niestety nie w ASP.

Div’a zastąpił mi Panel, a przycisk po wciśnięciu którego pojawia się panel, powstał jako oddzielna kontrolka (także kompozytowa). Wszystko ładnie złożyłem i opakowałem w metodę CreateChildControls(). Ku mojemu zdziwieniu JavaScript wywoływany po wciśnięciu przycisku powodował błąd. Okazuje się, że ClientId panelu jest puste (względnie nie zawiera wartości, której się spodziewam). Dlaczego? Otóż ClientId nie jest dostępne z poziomu metody CreateChildControls(), prawidłową wartość możemy uzyskać dopiero tuż przed wyrenderowaniem kontrolki, czyli np. na preRenderze.

protected override void OnPreRender(EventArgs e)
{
	// tutaj możemy się odwołać do ClientId kontrolek
}

Faktem jest, że unikalne ID tagów html’owych generowanych przez ASP może być zbudowane tylko przy kompletnym drzewie kontrolek, ale czy nie można było zaoszczędzić czasu i napisać o tym w dokumentacji właściwości ClientId?

‘asp’ is an unrecognized tag prefix or device filter

… czyli co zrobić gdy Visual Studio nie rozpoznaje tagów asp

Kilka dni temu powróciłem do naszego starego projektu w ASP.NET, w celu dodania kilku nowych fajerwerków. Ponieważ już od jakiegoś czasu nie miałem styczności z ASP musiałem poświęcić chwilę na małe rozpoznanie i przygotowanie stanowiska pracy. Gdy tylko usiadłem do Visual Studio 2005 (Web Developer), powróciły przykre wspomnienia dotyczące SourceSafe’a i pracy z całym środowiskiem. Jednym z bardziej wkurzających komunikatów, które zobaczyłem podczas ponownego wdrażania się w projekt był “słynny” “‘asp’ is an unrecognized tag prefix or device filter”. Czyli coś w stylu, VS informuje, że nie potrafi rozpoznać tagów ASP. Ręce mi opadły.

Z tego co udało mi się ustalić, rozwiązań jest kilka w zależności od problemu i skomplikowania projektu.

  • jeśli korzystasz z szablonów Master Page, a błąd występuje na podstronie dziedziczącej z szablonu lub używającej go, można uniknąć błędu otwierając w edytorze wykorzystywany szablon Master Page (głupie, ale na prawdę pomaga).
  • edytor VS 2005 bazuje na dynamicznie generowanych XML schemes, opisujących kontrolki ASPowe. Stąd błędy w wygenerowanych plikach mogą powodować wspomniany wcześniej komunikat. Rozwiązaniem w takim wypadku jest zamknięcie VS i wyczyszczenie katalogu zawierającego schematy xml. Katalog znajduje się pod adresem:
    C:\Documents and Settings\[Username]\Dane aplikacji\Microsoft\VisualStudio\8.0\ReflectedSchemas

    Po wyczyszczeniu katalogu należy ponownie uruchomić VS. Teraz schematy powinny się wygenerować na nowo i teoretycznie problem jest rozwiązany.

  • Komunikat o nierozpoznaniu tagów ASP może pojawić się również gdy w kodzie występują błędy, które uniemożliwiają jego kompilację. Zazwyczaj usunięcie błędów prowadzi do ponownego zaakceptowania tagów ASP.

Problem z rozpoznawaniem tagów ASP jest o tyle dziwny, że w 99% kod kompiluje się pod IIS, ale niestety nie działa pod VS.

W razie dalszych problemów polecam zapoznanie się z wątkami:
http://blogs.msdn.com/mikhailarkhipov/archive/2005/04/21/410557.aspx i
http://forums.asp.net/p/873238/883002.aspx#883002

Pierwszy z nich to blog developera VWD, zaczerpnąć informacji bliżej źródła już się chyba nie da;)

Szara codzienność programisty…

… czyli programowanie w stylu wolna amerykanka ;)

Dziwny program - komiks

Obrazek pochodzi z serwisu komiksy.onet.pl.

I Warszawskie Warsztaty Javowe

Warszawskie Warsztaty Javowe

W sobotę 17 listopada w godz. 9:00-17:00 odbędą się bezpłatne warsztaty Javowe. Miejsce spotkania to budynek MIMUW przy ul. Banacha 2 w salach 3180, 4420 i 5440.

Impreza ta zorganizowana przez Warszawską Grupę Użytkowników Technologii Java polega na wspólnym tworzeniu aplikacji z wybranym oprogramowaniem lub technologią. Ideą spotkania jest budowanie aplikacji “na żywo”, z udziałem publiczności.

W programie są między innymi JAXB 2.0, JRuby on Rails, czyli łączenie Javy i Rubiego, Spring Framework, OSGi oraz spotkanie poświęcone praktycznemu wprowadzeniu do JavaServer Faces 1.2 z Apache Geronimo 2 w tle.

Więcej informacji na stronie warsztatów.

Hosting Windows na home.pl

Źródło: home.pl

Home.pl, jedna z największych polskich firm oferujących usługi hostingowe, uruchomiła ofertę “Hosting Windows“. Usługa ta pozwala na korzystanie z pełnej funkcjonalności platformy Microsoftu. Konfiguracja oparta jest o Windows Server 2003 i Microsoft SQL Server 2005. Rozwiązanie to pozwala na stworzenie w pełni funkcjonalnego serwisu opartego o technologie Asp.NET 2.0, Ajax i MsSQL. Więcej informacji pod adresem home.pl.

Memcached, z czym to się je?

Na memcached natknęliśmy się podczas projektowania systemu wielojęzyczności (i18n) jednego z naszych serwisów. Problemem była kwestia przechowywania tłumaczeń tekstów. Pomysłów było kilka:

  • tłumaczenia przechowywane w plikach PHP, odpowiedni plik ze stałymi będzie includowany podczas obsługi żądania strony,
  • tłumaczenia przechowywane w plikach XML, pliki będą doczytywane w miarę potrzeby,
  • tłumaczenia przechowywane w bazie danych, i na bieżąco wczytywane.

Wszystkie te podejścia mają jednak słaby punkt, otóż za każdym żądaniem strony, tłumaczenia muszą być wczytywane od nowa. Faktem jest, że wszystkie trzy metody zawierają w sobie pewien rodzaj cache’owania (wczytywane pliki są cache’owane przez system operacyjny, zapytania bazodanowe cache’owane są przez bazę danych), ale tak na prawdę żaden z nich nie oferuje optymalnego rozwiązania. Najgorszym spośród wyżej wymienionych rozwiązań jest chyba czytanie tłumaczeń z plików XML. Wyobraźmy sobie, że za każdym razem gdy skrypt napotyka napis, musi wczytać odpowiedni plik i przeparsować XML w celu znalezienia tłumaczenia. Dodajmy do tego średnio 100 użytkowników aktualnie korzystających z aplikacji webowej i mamy murowaną porażkę. Można oczywiście spróbować cache’ować napisy na czas żądania strony, ale trzeba wziąć pod uwagę, że tłumaczenia raz wczytane, nie będą się często zmieniać. Większość z nich jest również wspólna dla wszystkich użytkowników. Tutaj do akcji spokojnie można zaprząc memcached.


Den ganzen Beitrag lesen…

PHP kłóci się z POSTem i textarea

Kilka dni temu, podczas projektowania edytora tekstu zauważyłem ciekawe zjawisko dotyczące przesyłania danych POSTem i ich odbioru w PHP. Zjawisko to, a w zasadzie błąd, powoduje ucięcie pojedynczego znaku nowej linii podczas przesyłania formularza, pod warunkiem, że jest to pierwszy znak w przesyłanym tekście. Problem ten dotyczy tekstu edytowanego za pomocą html’owego textarea i występuje w PHP 4 i 5 (sprawdzałem na PHP 4.4.6 oraz PHP 5.2.2). Dodam, że efekt ten nie występuje gdy formularz jest przesyłany metodą GET.

Den ganzen Beitrag lesen…

Flyspray, Pligg, Facebook… dokumentacja i programowanie obiektowe

Ostatnio coraz częściej zastanawiam się co się stało ze wzorcami projektowymi, programowaniem obiektowym, dokumentacją kodu źródłowego… czy ktoś jeszcze tego używa? czy może to już zamierzchła przeszłość? Wystarczy się trochę rozejrzeć… i nawet daleko nie trzeba szukać.

Niedawno miałem przyjemność wprowadzenia kilku zmian dotyczących funkcjonowania FlySpray’a (dla nieobytych, jest to taki program do obsługi zgłoszeń, np. raportowania błędów). Okazuje się, że programiści FlySpray uznali, że komentarze w kodzie źródłowym, czy też jakiś rodzaj manuala dla developerów jest zupełnie niepotrzebny. Nie wiem w jaki sposób dalej rozwijają już i tak dosyć skomplikowany projekt. Chyba po prostu piszą go nieprzerwanie od samego początku.

Dalej szarpnęliśmy się na próbę zainstalowania pligga (taki serwis pozwalający na postawienie swojego digga). Niestety, ale pligg sam z siebie, po zainstalowaniu, namiętnie wypluwał notice’y i warningi. Postanowiliśmy więc, pogrzebać trochę w kodzie, a nuż okaże się, że to jakiś mały problem i będziemy mogli spokojnie cieszyć się naszym własnym wykopem :) To co zobaczyliśmy totalnie nas zaskoczyło (no może nie wszystkich - ja już powoli się przyzwyczajam ;)). Wolna amerykanka to mało powiedziane, kod pligga to po prostu ’starocerkiewny’ (mieszanka kodu php, html, css i javascript w jednym pliku :D). Miłym dodatkiem do tych atrakcji jest również brak dokumentacji…

Na koniec zostawiłem sobie ostatnią nowinkę ze świata wielkich społeczności. Niedawno, w cudowny sposób, wypłynął na wierzch kod jednego z największych, społecznościowych serwisów, mowa oczywiście o Facebook. Co się okazało? Facebook również napisany jest w starocerkiewnym. Ech…

O ile można próbować wytłumaczyć styl programistów Facebook’a, którzy nie planowali upubliczniania swojego kodu, o tyle dziwi mnie postępowanie programistów dwóch pozostałych aplikacji. Przecież projekty open source są z zasady otwarte i każda osoba może przeanalizować kod źródłowy. Wydaje mi się, że jest to wystarczający powód aby utrzymywać w miarę porządny styl programowania i znośną dokumentację. Jeśli to za mało, można również dodać, że porządnie udokumentowane i prawidłowo napisane aplikacje pozwalają na zdecydowanie łatwiejsze rozwijanie i mniejsze koszty utrzymania.

Zobaczymy co będzie dalej, z niecierpliwością czekam na kolejną wersję FlySpray’a :)