Zgodnie z zapowiedzią, dzisiaj będziemy implementować moduły, które coś z podanym tekstem robią. Do tego celu głównie używać będziemy wyrażeń regularnych.
1. Na pierwszy ogień pójdzie poprawiacz spacji. Jak często trafiają się wam dokumenty formatowane za pomocą 20 spacji? Za pomocą tego cuda wywalimy wszystko co ma powyżej dwóch za koleją.
class SpaceFixer implements TextJob {
public function process($string) {
$string = trim($string);
$string = preg_replace('/\s{2,}/' , ' ' , $string);
return $string;
}
}
Zasada działania prosta: najpierw wyrzuć wszelkie spacje przed i za stringiem, a następnie poszukaj dwie lub więcej spacji za koleją i zamień je na pojedyncze.
2. Teraz coś sporo trudniejszego: dodawacz twardych spacji do spójników. Zasada działania taka: znajdź mi spację, pojedynczy znak, znowu spację i jeden lub więcej znaków (np. jedzenie_i_picie).
class AddNbsps implements TextJob {
public function process($string) {
$output = ''; // inicjalizujemy pustą zmienną, zostało mi to po Javie
foreach ($this->splitStringsByTagChar($string) as $split) {
$output .= substr($split , 0 , 1) == '<' ? $split : $this->fixLine($split);
}
return $output;
}
private function splitStringsByTagChar($string) {
return preg_split('/(<.+?>)/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
}
private function fixLine($line) {
return preg_replace('/(\s{1}[-\("\w]{1})\s{1}([-\)"\w]+)/' , '$1 $2' , $line);
}
}
Jak widać trochę się pokomplikowało. Po co nam te dodatkowe funkcje? Ano po to żeby nie popsuły się nasze HTMLowe tagi. Funkcja splitStringsByTagChar niezachłannie szuka czegoś co przypomina sekwencję <coś> i szatkuje nam ciąg do tablicy.
Operator trójargumentowy po foreach sprawdza czy element tablicy zaczyna się od znaku < . Jeżeli tak, to zostawia go w spokoju, a jak nie, to kieruje do przeróbki do fixLine. Można zauważyć, że oprócz klasy znaków \w (alfanumeryczne i _) dodałem również ” ( ). Po przeanalizowaniu kilku tekstów stwierdziłem, że tak lepiej działa (a mogłoby pewnie lepiej gdybym poświęcił na to jeszcze trochę czasu).
3. Wyszukiwacz linków.
class AddLinks implements TextJob {
public function process($string) {
return preg_replace('`(?<!href="|src=")((https?://|www\.)[\w{1,}./?=#&]+)`i' , '<a href="$1">$1</a>' , $string);
}
}
Tutaj można zauważyć dziwną konstrukcję (?<! Jest to asercja wsteczna. Działa tak: znajdź mi ciąg znaków zaczynający się od http:// lub www., a jak znajdziesz, to sprawdź czy czasami przed znalezionym ciągiem nie ma konstrukcji z asercji. Po co to? Do wykrycia, czy link znajduje się już w tagu <a href=” lub <img src=”, a więc czy nie popsujemy kodu html. Do tego mógłbym równie dobrze użyć funkcji szatkującej z poprzedniego modułu, ale chciałem żeby było trudniej
Jak tego wszystkiego używać? Dosyć prosto: w atrybutach podajemy moduły, które nas interesują i podajemy tekst:
$jakisTekst = 'Ala ma kota, a kot ma HIV';
$txtProcesser = TextProcesser::getInstance(array('SpaceFixer','AddNbsps','AddLinks'));
$processedTxt = $txtProcesser->processJobs($jakisTekst);
Tekst będzie przetwarzany w podanej kolejności. Fajne, co?
[czeka na oklaski]


