1. Jak zamienić datę w formacie 'dd-mm-rrrr' na 'rrrr-mm-dd' ? Zakładamy, że dni i miesiące można podać jako cyfry, a w wyniku mają być zawsze dwucyfrowe:
echo preg_replace( '/([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})/ie', "'\\3-' . str_pad( '\\2', ( 3-strlen( '\\2' ) ), '0', STR_PAD_LEFT ) . '-' . str_pad( '\\1', ( 3 - strlen( '\\1' ) ), '0', STR_PAD_LEFT )", $date );

UPDATE: Zrezygnowałem z użycia str_pad na rzecz sprintf co znacznie skróciło regułkę:
preg_replace( '/([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})/ie', "'\\3-' . sprintf( '%02d-%02d', '\\2','\\1' )", $date );
Autor: Marek Będkowski
2. Jak zrobić regułkę która sprawdzi czy na końcu adresu jest ukośnik (/) ? W przypadku gdy chcemy mieć ładne url'e, ale nasze wirtualne katalogi nie będą tak interpretowane przez przeglądarke jeżeli adres nie zakończy się właśnie ukośnikiem.
Chcemy zeby skrypt rozpoznał że adres wygląda np tak:
http://br-webdesign.net/projects
I zamienił go na adres:
http://br-webdesign.net/projects/
Jak widać różnia sie "tylko" ukośnikiem na końcu.

No ale dosc gadania - do dzieła:

if( !preg_match('%(?(?!\.html|php)/$)%',( $s=$_SERVER['REQUEST_URI'] ) ) ) { header( 'Location:' . $s . '/' ); }


Jak widać od razu jest to wyższa szkoła jazdy, mianowicie są tutaj zastosowane warunkowe wyrażenia regularne. Sprawdzanie jest czy na końcu adresu nie występuje rozszerzenie pliku znanego typu. Specjalnie wyróżniłem napis nie występuje bo w php można zrobić regułke która wymaga, aby dany element znajdował sie na końcu stringa, ale także można zabronić jego wystąpienia i to właśnie się dzieje w naszym przpadku. Następnie jeżeli już wiemy, że adres nie kończy sie rozszerzeniem, to sprawdzamy czy aby nie zawiera na końcu ukośnika (wtedy wysyłanie header'a nie miałoby sensu) no i jeżeli nie to wysyłamy odpowiedni komunikat do przegladarki.
Autor: Marek Będkowski
3. Jak zamienić date używając składni funkcji date na odpowiedni ciąg? Otóż zdarzyła mi sie taka sytuacja w której, aby umożliwić użytkownikowi dowolne formatowanie daty, pobieranej z bazy jako unixowy znacznik czasu, trzeba było zrobić system jej konwersji zgodny z parametrami funkcji date, czyli np. ciag d-m-Y, dla znacznika "1107942070" pownien zostać zamienony na "09-02-2005". Na początku podejście było strasznie kombinatroskie, czyli jakies explode'y, pętle i strasznie dużo kodu, a wystarczy tak naprawde jedna, dość krótka regułka:

preg_replace( '%([\w])%e', "date( '\\1', $iTimestamp )", $sDate );


Autor: Marek Będkowski
4. Jak wydobyć z ciągu znaków tabelkę z dowlną liczbą zagnieżdżeń? No to kolejny cieżki orzech do zgryzienia. Na początku wydawał sie bajecznie prosty, ale szybko okazało sie, że zwykłe regułki juz tutaj nie dadzą rady, wiec zdecydowałem sie na reukrencje.

W sumie dość ciężko mi opisać działanie, bo
$GLOBALS['depth'] = 0; function getOpen($sString){ if( preg_match( '%(]*>)(.*?)(.*)%si', $sString, $aMatches ) ) { getOpen( $aMatches[2] ); $GLOBALS['depth']++; } return array( $aMatches[1].$aMatches[2], $aMatches[3] ); } function getClosed( $s ) { if( $GLOBALS['depth']-- && preg_match( '%(.*?)(.*)%si', $s, $aMatches ) ){ return $aMatches[1] . getClosed( $aMatches[2] ); } } $aResult = getOpen( $sString ); echo $aResult[0] . getClosed( $aResult[1] );
Autor: Marek Będkowski
5. Jak pobrać nagłówki wiadomości email? No wiec mamy np taka wiadomość e-mail:
Reply-To: "Marek Bedkowski" <marek.bedkowski@bla.com>
From: "Marek Bedkowski" <marek.bedkowski@bla.com>
To: "marek Bedkowski"
Subject: =?iso-8859-2?Q?bla_bl=B6cie=BFka_bla__bla_bla_bla_bla_?=
 =?iso-8859-2?Q?_bla_bla_bla_bla_bla_bla_bla_bla_bla_?=
 =?iso-8859-2?Q?la_bla_bla_bla_bla_bla_bla_bla_bla?=
 =?iso-8859-2?Q?_bla_bla_bla_bla_bla_bla_bla_bla?=
 =?iso-8859-2?Q?la_bla_bla_bla_?=
Date: Tue, 12 Apr 2005 15:46:42 +0200
MIME-Version: 1.0
Content-Type: text/plain;
charset="iso-8859-2"
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Unsent: 1
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
X-Virus-Scanned: by amavisd-new at bla.com

This is a message in MIME format.
Zadanie jest o tyle trudne, że tekst jest porozbijany na nowe linie, a nową linia oddziela także kolejne nagłówki od siebie, ale i tak no to da się coś poradzić:

#^([\w-]+): (.+)\r?\n(?!\t| )#Umsi

Wyrażenie najpierw pobiera nazwę nagłówka, później oddzielający dwukropek wraz ze spacja (ona jest częścią specyfikacji), a następnie leci do znaku nowej linii (jak widzicie wzięte pod uwagę są też windowsowe znaki nowej linii) , jednak nie bierze pod uwage tab'ow ani spacji, bo nimi moga być oddzielone od siebie części wieloliniowego nagłówka (znaczy takie które mają więcej niż 74 znaki i zostały podzielone).

Niby proste a jednak...
Autor: FiDO, Marek Będkowski (Dyskusja na php.pl)
6. Jak rozpoznac ciag cyfr oddzielony palkami? Otoz pojawil sie kolejny problem. Tym razem chodzi o zamiane jednej palki (|) w ciagu cyfr oddzielonych tymze wlasnie elementem.
np. 1|2|3|4 3|2|3|4 2|2|3|4 1|3|2|4
I teraz sa 3 warunki (wyrazenie narazie spelnia pierwsze 2 :():
- liczby o ktore nam chodzi to 2 i 3 w dowolnej, niepowtarzajacej sie, kombinacji (2|3 lub 3|2 ale 3|3 i 2|2 juz nie pasuja)
- para liczb musi byc poprzedzona 1 lub 4 i konczyc sie 1 lub 4
- para liczb moze takze wystapic na poczatku lub na koncu ciagu (wtedy takze aplikuje sie czesciowo regula numer 2, zalezna od tego gdzie szkany ciag wystepuje)

Narazie regulka wyglada tak:

$_ = '1|2|3|4 3|2|3|4 2|2|3|4 1|3|2|4'; $_ = preg_replace( '/([14])\|(?:(?:(2)\|(3))|(?:(3)\|(2)))\|([41])/', '$1|$2$4$3$5|$6', $_ ); echo '
';
print_r( $_ );



Autor: Marek Będkowski
7. Jak zwalidować adres email? Oto mój ostatni wynalazek w sprawie walidacji emaila. Niezbyt uperdliwa regułka, aczkowliek wyłapująca wiekszość błędów:
'/^[\w.-]+@([a-z\d][a-z\d-]*\.)+([a-z\d]{2,4})$/i'
Autor: Marek Będkowski
8. Jak zamienić adresy www w tekście na linki? No i tak oto moja odpowiedź, na powtarzający się problem zamiany URL'i w plain text, na odpowiadające im linki. Od samych adresów wymagane jest tylko, żeby przed nimi występował jakiś znak, ale to chyba da się zrobić.
$s = '%2$s'; $arRegExp = array( '!(?<=[.,;:\s])(http(s?)://)?(?(1)(www\.)?|(www\.))(.*?)(?=[,;:\s])!ie' ,'/([[:alnum:]]([\w.:-])?)+@([[:alnum:]][\w.:-]+[[:alnum:]]\.)?((([[:alnum:]]([\w.:-]{1,59})?[[:alnum:]])|[[:alnum:]]).)([a-z]{2,4}|[0-9]{1,3})/is' ); $arReplace = array( 'sprintf( $s, "$2", "$3$4" . rtrim( "$5", "." )) . ( substr( "$5", - 1 ) == "." ? "." : "" )' ,'$0' ); $sString = preg_replace( $arRegExp, $arReplace, $sString );
Autor: Marek Będkowski
9. Jak zamienic elementy src= bez tych które zawierają http://? Kolejny problem z którym przyszło się zmierzyć dotyczył sposobu w jaki pobrać atrybut src (względnie href), ale tylko w przypadku gdy jego wartość nie zaczyna sie od http://.
Jest to w miarę prosty sposób, żeby zmienić wygląd linków prowadzących do zewnętrznych stron (tak jak u mnie na stronie).
#src=('|")?((?!http://).*?)(?(1)\\1| )#
No i co my tutaj mamy?
Otóż zaczynamy od oznaczenia nazwy atrybutu (src), następnie podajemy, że ma zwracać uwagę na cudzusłowy, aż do zamknięcia. Zastosowałem także tzw. negative loookup, które po poprawnym zweryfikowaniu wzroca, sprawdza go w odwrotnym kierunku (od prawej do lewej) w celu wykluczenia elementów które zawierają http://.
Autor: Marek Będkowski
Jeżeli masz jakieś wyrażenie, które można dopisać do listy proszę o kontakt
Marek Będkowski