Zdravím ;o)
Potřeboval bych odfiltrovat text pomocí regulárního výrazu, který by smazal každý řetězec, který by obsahoval více jak 4 stejné znaky jdoucí po sobě.
Takové to typické fffffffffffffffff
Nepodařilo se mi říct skriptu, aby to byla libovolná písmena jdoucí několikrát PO SOBĚ.
Díky
Třeba takhle to nahradí všechny mnohonásobné opakování pouze třemi. Takže následující vypíše "Ahoooj, jak se maaas?"
echo preg_replace("/(.)(\\1){3,}/", "\\1\\1\\1", "Ahoooooooooooooooj, jak se maaaaaaaaaaaaaaaaaaas?");
<HTML>Pres RE by to slo docela blbe, ale jde na to napsat jednoducha funkce:
function one($str) {
$i = 1;
while ($i < strlen($str)) {
if ($str[$i] == $str[$i-1]) return 1;
$i++;
}
return 0;
}
Pri nalezeni vice opakovanych znaku po sobe vraci 1, jinak 0.</HTML>
Stilett: To je přesně ono :o)
Akorát bych potřeboval, jestli byste mi vysvětlili dvě věci, protože jak je vidět, ještě v regulárních výrazech nejsem úplně zběhlý. Proč na začátku a na konci reg.výrazu je zpětné lomítko, normálně ho nemuím používat a když jsem ho zkusil odstranit tak to samozřejmně hodilo chybu. A pak co přesně znamená v reg.výrazu to \\1 ? Měl jsem za to, že se to používá k vytažení určité části reg.výrazu, ale jak vidím, tak to není úplně pravda (pouze)
Jinak ještě jednou díky za odpovědi ;o)
Je to v tom, že se musí použít Perl-Compatible RE, který se trochu liší od Posixových. Jednou z odlišností je právě použití ohraničovacích znaků (může být i jiný, ale / se používá běžně). Za ně se zapisují pouze modifikároty (např. v RE "/ahoj/i" to i značí case-insensitive porovnávání). A ta \\1 je tzv. back-reference, odkaz na předchozí část (stejně jako v nahrazovacím řetězci, tedy nic nového). Výraz funguje takto:
Tečka sedne na libovolný znak. Jelikož je v závorce, tak se zachytí jako subpattern s číslem 1. Následně se testuje jestli se obsah té první závorky (ke němuž se dostaneme právě oním \\1) opakuje ještě alespoň 3x.