[PHP]Potíže s mb_ereg

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Václav M. 3. 10. 2020 21:45

Jelikož preg_match nepodporuje Unicode, rozhodl jsem se (kvůli českým znakům) pro použití mb_ereg.

A zkusil jeho funkčnost na svém jménu, které jsem pomocí funkce mb_substr rozložil na jednotlivá písmena (uložená v poli). Každé písmeno jsem nechal porovnat s jednoduchým výrazem obsahujícím znakovou třídu v POSIX tvaru (tedy [:graph:] atd.)

Vybrané znakové třídy byly: alnum, punct a cntrl.

Výsledek měl být pole, v němž se měla šestkrát objevit třída alnum. Tato třída se sice v poli objevila, ale ne šestkrát, ale pouze jednou. A dvakrát se objevila třída cntrl. To tedy nechápu.

Odkdy se v slově Václav vyskytují řídící znaky?! A proč některá písmena nepoznal?

O zjišťování znakových tříd se stará tato metoda:
Kód: Vybrat vše
private function Get_CharacterClasses($Character)
{
   $CharacterClasses = NULL;

   switch($this -> CharacterClassesMode)
   {
      case 0:
         foreach(LoadInternals::RegexpGraphMode() as $Class)
         {
            if(mb_ereg($Class, $Character))
            {
               $CharacterClasses = $Class;
            }
         }
         break;
      case 1:
         foreach(LoadInternals::RegexpAlnumMode() as $Class)
         {
            if(mb_ereg($Class, $Character))
            {
               $CharacterClasses = $Class;
            }
         }
         break;
      case 2:
         foreach(LoadInternals::RegexpAlphaMode() as $Class)
         {
            if(mb_ereg($Class, $Character))
            {
               $CharacterClasses = $Class;
            }
         }
         break;
      case 3:
         foreach(LoadInternals::RegexpStrictMode() as $Class)
         {
            if(mb_ereg($Class, $Character))
            {
               $CharacterClasses = $Class;
            }
         }
         break;
   }

   return $CharacterClasses;
}


Dle nastavení použitých znakových tříd se každý znak zkontroluje, zda vyhovuje znakovým třídám ze seznamu.

Seznamy znakových tříd jsou sestaveny tak, aby (pokud možno) žádný znak nemohl mít dvě či více znakových tříd.

:arrow: :?:
Chyba může být v nastavení - resp. v špatném použití či nepoužití nějaké další funkce, kterou je nutné použít. Ale nevím, kterou a jak použít.

Zatím mám použitu pouze funkci mb_regex_encoding s parametrem UTF-8 - a tu mám použitu na začátku metody, v níž je výše uvedená metoda volána.

:arrow:
Původně jsem měl použitu funkci preg_match. Ta sice nepoznala české znaky, ale znaková třída u ostatních znaků byla uvedena správně.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 4. 10. 2020 07:47

Upřímně, chvíli jsem tápal, ale po vyzkoušení pár věcí jsem narazil na to, že str_split mi zkazil znaky, tak jsem zkusil mg_ereg pro každé písmeno manuálně. Mělo by to fungovat i pro celý text, ale hádám, že je jiný záměr.

Každopádně při použití alnum to vzalo á a ý - pro punct to bylo prázdné

Kód: Vybrat vše
<?php

//mb_regex_encoding( 'UTF-8' ); <-- u mě nemělo vliv

$nn = 'Múůártin Jánský';

for( $idx = 0; $idx < mb_strlen($nn); $idx++)
{
   $n[] = mb_substr( $nn, $idx, 1);
}

for($i=0;$i<count($n);$i++)
{
echo $n[$i]."\n".PHP_EOL;
mb_ereg('[[:alnum:]]',$n[$i],$a);
var_dump($a);
}

?>
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 4. 10. 2020 21:26

Just_jo píše:Upřímně, chvíli jsem tápal, ale po vyzkoušení pár věcí jsem narazil na to, že str_split mi zkazil znaky, tak jsem zkusil mg_ereg pro každé písmeno manuálně.

Tedy, text naneštěstí nemá ani hlavu, ani patu.

Funkce str_split fungovat nemohla, protože není Unicode ready. Místo ní by bylo nutné použít mb_str_split. Ale i ta jen rozloží řetězec na menší díly. Takže manuální použití vzorce [[:alnum:]] pro každé písmeno nemá s nefunkčností str!_split na Unicode řetězce nic společného.

Jen použití (mb_)substr s iterací řetězcem by se dalo nahradit použitím (mb_)str_split. Výsledek by měl být shodný.

Mělo by to fungovat i pro celý text, ale hádám, že je jiný záměr.

...ale díky za ty dvojité hranaté uvozovky. Když jsem přepisoval původní výraz určený pro funkci preg_match, tak jsem je (omylem) zrušil i s těmi ohraničujícími lomítky.

Že
Kód: Vybrat vše
mb_regex_encoding( 'UTF-8' );
nebude mít vliv, je celkem jasné, když UTF-8 je od jisté doby (PHP 5.6.0) výchozí kódování. Ale myslím, že tento řádek navíc nevadí.

:arrow:
Záměrem bylo (v různých modifikacích - na nich však ještě musím zapracovat) podle předloženého řetězce sestavit regulární výraz. A ten využít k porovnání dalšího řetězce. Tedy porovnávat zda dva řetězce odpovídají stejnému vzoru - bez ohledu na jejich obsah.

Dle nastavení by tak řetězce (např.) Odpor je marný a Přišli jsme vydělat mohly vyhovět - nebo také ne.
Václav M.
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 5. 10. 2020 15:32

OK - ohledně unicode support - nějak jsem toto neřešil. Málokdy toto používám.

Takže je nějaká část problému vyřešená? Nebo je stále něco k dořešení?
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod Václav M. 5. 10. 2020 17:12

Vyřešeno. Problém byl v závorkách.

Zbytek už nemá s předmětem téma nic společného a jde pouze o způsob řešení.
Václav M.
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků