Autor Zpráva
nethor
Profil
Zdravím, prosím, poraďte mi s regulárem.
Potřebuji , aby vyhověly řetězce "/2018/-x-user" , "/2019/-x-user", ... viz kód níže, jen ne "/2021/-x-user".

Nevím proč mi asertivní negace nefunguje.

$Text = "/2018/-x-user"    ;    
$Text = "/2019/-x-user"    ;    
$Text = "/2019-08/-x-user"    ;
$Text = "/2020/-x-user"    ;    
$Text = "/2021/-x-user"    ;     // nesmí vyhovět
    
preg_match('~/(?!2021)/-x-user~i', $Text , $Arr)     ;
// preg_match('~/20(?!21)/-x-user~i', $Text , $Arr)     ; // eventuelně
Kcko
Profil
nethor:

preg_match('~/(?<!2021)/-x-user~i', $Text , $Arr)

infoheap.com/php-look-ahead-look-behind-regex
nethor
Profil
Kcko:

To nefunguje.

Zkoušel jsem též:
// $Text = "/2017/-x-user"    ;    
// $Text = "/2019/-x-user"    ;    
// $Text = "/2019-08/-x-user"    ;
$Text = "/2020/-x-user"    ;        


// $Regular = "/(?!2021)/-x-user"    ;    
// $Regular = "/20(19|20)/-x-user"    ;
// $Regular = "/(?:(?!2021))/-x-user"    ;
$Regular = "/(?<!2021)/-x-user"    ;    


$Return = preg_match('~'.$Regular.'~i', $Text , $Arr)     ;

echo "<div class='Vard'>$Text:<xmp>".$Text."</xmp></div>";
echo "<div class='Vard'><b>".__FILE__." \$Return </b><xmp>";var_dump($Return);echo "</xmp></div>";
echo "<div class='Vard'><b>".__FILE__." \$Arr </b><xmp>";var_dump($Arr);echo "</xmp></div>";
tttttttttttt
Profil *
Look ahead a look behind pokud si dobře pamatuju "nesežerou" žádnou část textu, tj. /(?!2021)/-x-user se vyhodnotí jako dvě lomíkta za sebou, přičemž před tím druhým nesmí být 2021 (což platí vždy, když to matchuje, je tam lomítko).

Pozitivní přístup je jednodušší. V příkladech ho vidím, zdá se mi, že by měl fungovat, pokud se rozšíří na další roky. Co tohle?
$Regular = "/20([0-1][0-9]|20)/-x-user"
Keeehi
Profil
~(?<!/2021)/-x-user~i
Tohle je regulár který ten rok 2021 vyhodnotí správně. Ovšem v $Arr se nedozvíš, co za rok tam bylo. Jediné čím si můžeš být jistý je, že tam nebylo /2021. Což v některých případech může úplně stačit. Ovšem v takovém případě stačí otestovat jednoduše výskyt řetězce /2021/-x-user (a to i bez regexpů) a jen provést negaci.

No a nebo pak tam ty čísla mezi lomítka přidat.
/\d{4}(?<!2021)/-x-user
nethor
Profil
tttttttttttt:
Na tom se mi nelíbí ta otročina, vyjmenovávat vše, co má projít. Protože vycházím z toho, že bezpečně vím, co projít nemá.

Keeehi:
Děkuju. „~(?<!/2021)/-x-user~i“ funguje. V mém případě opravdu stačí, že vím, že tam nebylo /2021.
Ikdyž tedy vůbec nechápu, proč to chodí po přesunutí lomítka. Popravdě mám za to, že by měla fungovat ta první var. "/(?!2021)/-x-user"
Nicméně případ vyřešen, ještě jenou díky.
tttttttttttt
Profil *
nethor:
Popravdě mám za to, že by měla fungovat ta první var. "/(?!2021)/-x-user"

Look forward/behind dělají něco odlišného od jiných konstrukcí, popisují vlastnost, co má výraz před/za mít, ale samy na nic nematchují. /(?!2021) znamená lomítko (jeden znak!), za kterým není 2021. Neznamená to lomítko a pak 'cokoliv kromě 2021' . Proto funguje i Keeehiho /\d{4}(?<!2021)/-x-user, což lze číst jako lomítko, pak čtyři číslice, pak lomítko, před kterým není 2021. Ve výrazu, který jsi uváděl, je lomítko, za kterým není 2021, pak lomítko. Je to takto srozumitelnější?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0