Autor Zpráva
Amunak
Profil
Mám těchto pár funkcí na jednoduché přidávání smajlíků do chatu (viz níže). Problém je v tom, že smajlík, kde je použita závorka, nefunguje. Projde všemi kontrolami (včetně té, jestli jeho popis odpovídá jeho reg. výrazu), ale v textu se potom nepřevede. Předpokládám, že je to tím oescapováním v řetězci, ale nevím, jak to vyřešit.)

$smile_search = array();
$smile_replace = array();
$smile_dump = array();

/**
 * Adds a smile to the smile list.
 *
 * Conditions:
 * - Smile have to exist
 * - Smile have to be a PNG file
 * - Maximum smile width is 64px
 * - Maximum smile height is 16px
 * - Smile description have to match the regexp
 *
 * @global array $smile_search
 * @global array $smile_replace
 * @global array $smile_desc
 * @param string $regexp        What to search in text (central part of a regular expression, eg.: ;-?D)
 * @param string $link          Name of the .png file in folder smilies
 * @param string $desc          Description for ALT and TITLE, it have to match the regexp (eg.: ;-D)
 */
function addsmile($regexp, $link, $desc) {
    $file = 'smilies/' . $link . '.png';
    if (file_exists($file)) {
        $iifo = getimagesize($file);
        if ($iifo[0] > 64 || $iifo[1] > 16 || $iifo['mime'] != 'image/png') {
            echo '<!-- WARNING: Smile "' . $file . '" is not a PNG file or is greater then 64x16px -->';
            return false;
        } elseif (!preg_match('/^' . $regexp . '$/is', $desc)) {
            echo '<!-- WARNING: Smile description "' . $desc . '" does not match the "/^' . $regexp . '$/is" expression -->';
            return false;
        } else {
            global $smile_search, $smile_replace, $smile_dump;
            $smile_search[] = '/\B' . $regexp . '\b/is';
            $smile_replace[] = '<img class="smile" src="' . $file . '" alt="' . $desc . '" title="' . $desc . '">';
            $smile_dump[] = '<a href="#" onclick="fillForm(\'' . $desc . '\', \'r\');"><img class="smile" src="' . $file . '" alt="' . $desc . '" title="' . $desc . '"></a>';
            return true;
        }
    } else {
        echo '<!-- WARNING: Smile "' . $file . '" doesen\'t exists -->';
        return false;
    }
}

addsmile(':-?\)', 'smile', ':-)'); //Tento smajlík nefunguje
addsmile(':-?D', 'grin', ':-D'); //Tento smajlík funguje

/**
 * Apply a BBCode to a string.
 * @global array $smile_search
 * @global array $smile_replace
 * @param string $texto input string
 * @return string
 */
function bbcode($texto) {
    global $smile_search, $smile_replace;

    /* BBCode */
   //Tady jsou značky, fungují v pořádku

    /* EMOTICONS */
    $texto = preg_replace($smile_search, $smile_replace, $texto);

    return $texto;
}
AM_
Profil
Zkus si napsat prostý výraz
echo preg_replace('/\B:-?\)\b/is', '-replacement-', 'ahoj:-)');

a na tomto kousku výraz odladit.

Moc nechápu, proč chceš, aby před smajlíkem nebyla hranice slova (\B) a za smajlíkem ano (\b), nedělá náhodou problém to? podle mě to znamená, že těsně před smajlíkem musí být non-word character a za ním word character.
Také mi na smajlíky přijde zbytečný přepínač "s", pokud neplánuješ víceřádkové smajlíky je tam nanic, ale v tom problém asi nebude.
Amunak
Profil
AM:
Je to zvláštní. Odstranil jsem tedy přepínač s, a z obou B jsem udělal velká. Efekt se otočil: funguje :), ale nefunguje :D.
Když z obou B udělám malá, nefunguje ani jeden. Viz můj problém zde.
AM_
Profil
A co kdybys ta \B úplně vyhodil? podle mě jsou tam k ničemu, to se používá k ohraničování slov, nikoli smajlíků.
Amunak
Profil
AM:
Ale jak jinak docílit toho, aby se text as:df nepřevedl na smajlíka? použít jiné značky (teď nevím jestli to bylo \w nebo \s) se nějak nepovedlo, ale přinejhorším to asi udělám.
Str4wberry
Profil
Osobně nevidím důvod do toho tahat regulární výrazy.
Amunak
Profil
Str4wberry:
Já jo... case-insensitive se sice dá udělat přes ireplace, ale přijde mi lepší regulár než stále vypisovat verzi s pomlčkou i bez ní. Navíc bych to pak musel řešit v poli smile_dump, které smajlíky vypisuje v seznamu. Objevily by se v něm totiž dvě verze.
AM_
Profil
Amunak:
Ale jak jinak docílit toho, aby se text as:df nepřevedl na smajlíka?
jenže to tam nemůžeš naprat takhle obecně, tak to \b dávej do individuálních výrazů pro každého smajlíka dle uvážení a ne pevně před a za všechny. Třeba v případě :D tam \b na konci smysl dává, v případě :) nejenže nedává, ale ani to nebude fungovat.
Amunak
Profil
AM:
Třeba v případě :D tam \b na konci smysl dává, v případě :) nejenže nedává, ale ani to nebude fungovat.
Jakto ale? Mohl bys mi to, prosím, vysvětlit?
AM_
Profil
Něco si o \b přečti. Jde o to, že kupříkladu v "Ahoj:-) jak se máš?" ty matchuješ:
Před :-) se zde nachází hranice slova (končí "ahoj"), takže nepředchází \B. za smajlíkem hranice slova naopak není (smajlík končí závorkou a za ním je mezera, což není považováno za "word boundary"), takže ani \b na konci neprojde.
Měj také na paměti, že \B a \b, jsou nulové délky, podobně jako znaky pro začátek ^ a konec $ - nematchují žádný znak, ale vlastně mezeru nulové velikosti mezi znaky a zda pro ni platí určitý výrok.
Amunak
Profil
AM:
No tak to jsem si přečetl, ale moc moudrý z toho nejsem. Asi zůstanu u plánu B, a to úplně se na tu kontrolu vykašlat :-D
Není to nic kritického, a navíc stejně počítám se zavedením "tagu" pro dočasné zakázání bb kódů.
Amunak
Profil
Tak jsem to nakonec přeci jen udělal tak, jak mi AM_ navrhoval - pro každý smajlík si napsat "word boundary" zvlášť. Akorát teď nevím, jak to napsat u smajlíka, který má variantu ;-) a ;-D. Pro ;-) by mělo být na konci \B, zatímco pro ;-D by tam mělo být \b.

Tuším, že by to šlo nějak se závorkami, ale nevím přesně jak. Stydím se sám za sebe, že jsem si to nenašel. Ale tady se najde určitě někdo ochotný mi to napsat. Navíc zaručeně správně. Díky.
AM_
Profil
úplně stejně jako všechno ostatní, tedy:
:-(\)\B)|(D\b)

ale stejně tu podle mě zbytečně šaškuješ s tím \B, řekněme že \b za D má docela smysl, když ale někdo napíše "Ahoj :-)jak se máš? :-)" nevidím rozumný důvod, proč :-) v obou případech nevzít jako smajlíka.
To, že \B je negace \b, neznamená, že kam nenacpeš \b máš cpát \B, někam prostě nepatří ani jedno.
Amunak
Profil
AM_:
Díky, použiju tenhle regulár a ještě teda promyslím, jestli ten konec ošetřovat ikdyž je tam závorka. Asi máš pravdu, že v tom případě je to zbytečné, protože vlastně třeba i já občas píšu :)) aby to byl jakože smajlík a pak ještě koncová závorka pro text, který byl v závorce. Možná nakonec vyhodím všechny ty koncové... Nicméně počáteční nechám, protože lepit na to text zepředu je prasárna.

Ještě jednou díky za pomoc. Téma považuji za vyřešené.
Toto téma je uzamčeno. Odpověď nelze zaslat.