Autor | Zpráva | ||
---|---|---|---|
MTF Profil |
Zdravím a prosím o pomoc. Nedaří se mi sestavit regulární výraz pro ověření jména souboru v tomto tvaru:
01-02-03-04.html - název souboru může obsahovat libovolný počet 2-ciferných subnázvů oddělených pomlčkou. Potřebuji pomoci fce preg_match ověřit správný tvar názvu souboru tak, aby parametr matches obsahoval jednotlivé části nazvu souboru. Zkoušel jsem toto: ^(\d{2})(?:-(\d{2}))*\.html$ array(3) { [0]=> string(17) "01-02-03-04.html" [1]=> string(2) "01" [2]=> string(2) "04" } Moderátor Joker: Titulek „další regulární výraz :)“ nevystihoval podstatu dotazu. Příště zkus prosím vymyslet lepší.
|
||
juriad Profil |
MTF:
Snažíš se provádět příliš věcí najednou. Můžeš napřed jen zkontrolovat, že název odpovídá požadavkům, a pak ho rozdělit na jednotlivé části: function parseFileName($fileName) { if (! preg_match('/^\d\d(-\d\d)*\.html$/', $fileName)) { return FALSE; } return explode('-', substr($fileName, 0, strlen($fileName) - 5)); } $name = '01-02-03-04.html'; var_dump(parseFileName($name)); |
||
Joker Profil |
#3 · Zasláno: 28. 1. 2014, 09:09:20
MTF:
Poznámka: Skoro mi připadá, že když se diskuse brání titulkům „Problém“, část tazatelů místo „problém“ používá „regulární výraz“. Většina dotazů pojmenovaných „Regulární výraz“ řeší nějaký konkrétní problém (tady rozdělení řetězce podle pomlčky) a regulární výraz tazatel předpokládá jako možné řešení. Přitom často regulární výraz není nejlepší řešení tazatelova problému (někdy dokonce problém ani rozumným způsobem přes RV řešit nejde). Jinak řešil bych to taky přes explode, jako juriad. |
||
MTF Profil |
#4 · Zasláno: 28. 1. 2014, 09:40:35 · Upravil/a: MTF
Díky za hbitou odpověď. Takže to nejde? Potřeboval jsem ten reg výraz pro porovnávací funkci pro usort. Jde o to, že tvar jména souboru by se mohl časem měnit např. na A_01-02-03.html. Tím pádem by se musela Tvoje funkce předělat. Ideální by bylo najít ten správný regex pokud to jde :-)
BTW: taky bych to řešil přes explode, kdyby to šlo :-) |
||
juriad Profil |
#5 · Zasláno: 28. 1. 2014, 10:00:01
MTF:
Myslím, že to přes regex nejde. V regexu vždy uvedeš jen konečný počet závorek (vzorů k zapamatování) a stejný počet bude ve vystupním poli matches. Pěkně to lze ilustrovat na příkladu: $names = array('a-bb-c-dd-e-ff-', 'a-b-c-d-e-f-', 'aa-bb-cc-dd-ee-ff-', 'aa-b-cc-d-ee-f-'); foreach ($names as $name) { preg_match('/^(?:(?:(\w)|(\w)(\w))-)*$/', $name, $matches); var_dump($matches); } Zkus popsat celý svůj problém s řázením, třeba to půjde vyřešit nějak jednoduše a možná nebudou regulární výrazy nakonec třeba. :) |
||
peta Profil |
#6 · Zasláno: 28. 1. 2014, 10:19:55
$str = "01-02-03-04.html"; $arr = explode('.',$str); $arr = explode('-',$arr[0]); print_r($arr[0]); 01-02-03-04.html - ^\d+(-\d+){3}\.html$ (tez vyhovuje pro 000-0-0-000.html) A_01-02-03.html - ^\w+_\d+(-\d+){2}\.html$ (tez vyhovuje pro xAss_0-000-000-0.html) http://www.regexp.cz/index.php Zvlastni, ze dvojka vyhovuje i 0A_01-02-03.html podle regexp.cz pro PHP preg. Samozrejme, muzes dusledne vyzadovat presne 2 cislice a aby byla prvni nula a pod. To zalezi na tobe. |
||
MTF Profil |
#7 · Zasláno: 28. 1. 2014, 10:23:50
juriad:
Ok, tušil jsem, že bude problém s těma subvýrazama :( Můj problém s řazením je prostý. Potřebuji ty soubory seřadit vzestupně dle abecedy (tedy číselné části řadit jako čísla a zbytek dle abecedy). Pomocí sort se mi to nedaří, proto jsem šel cestou usort. Pokud by byl tvar názvu souboru neměnný (tedy měl by omezený počet "subnázvů" třeba na 4, např. 01-02-03-04.html) tak s tím nemám problém. Ale chtěl jsem to udělat maximálně univerzální :-) |
||
Radek9 Profil |
#8 · Zasláno: 28. 1. 2014, 12:35:56
MTF:
Možná se podívej spíš na natsort. Není to to, co hledáš? |
||
MTF Profil |
#9 · Zasláno: 28. 1. 2014, 12:55:31
Radek9:
Úžasná funkce :-) to jsem přesně potřeboval. Jak to, že tu funkci neznám? :-) Díky! |
||
peta Profil |
Nemyslim, ze je to rozumny napad psat vlastni serazovani. Jak seradis:
01-02-03-04.html // 1-2 01-020-03-04.html // 1-20 1-02-03-04.html // 1-2 001-02-03-04.html // 1-2 010-02-03-04.html //10-2 <script> function sort_cb1(a,b) { return a - b; } function sort_cb2(a,b) { var i,l; a = a.split('-'); b = b.split('-'); l = a.length<b.length ? a.length : b.length; for (i=0;i<a.length;i++) { if (sort_cb1(parseInt(a[i]),parseInt(b[i]))>0) return 1; } return -1; } var t, arr; str = "\ 01-02-03-04.html,\ 01-020-03-04.html,\ 1-02-03-04.html,\ 001-02-03-04.html,\ 010-02-03-04.html,\ 001-20-03-04.html\ " arr = str.split(","); t = arr.join(",\n")+"\n\n"; arr = str.split(","); arr.sort(); // klasicky string sort t += arr.join(",\n")+"\n\n"; arr = str.split(","); arr.sort(sort_cb2); // rozparsovani a ciselny sort (serazuje, ikdyz je druhy string delsi a=1-2-3, b=1-2-3-4 t += arr.join(",\n")+"\n\n"; alert(t); </script> |
||
MTF Profil |
#11 · Zasláno: 28. 1. 2014, 13:41:41 · Upravil/a: MTF
Tak jsem se radoval předčasně :( ani natsort nesetřídí přirozeně tyto hodnoty:
01.html 02.html 02-01.html 03.html Jak to jenom ten Total Commander dělá? :-) Joker: a prosím moderátora, aby změnil zpět název diskuze na původní, případně na "Jak přirozeně setřídit pole" Díky! |
||
peta Profil |
MTF:
Mozna by bylo fajn dat sem priklad, jak to serazene potrebujes a proc to povazujes za prirozenejsi nez jine? Ja tu treba TC nemam a instalovat to na firemni pc ani nebudu. |
||
MTF Profil |
#13 · Zasláno: 28. 1. 2014, 14:13:24
peta:
Soradž, potřebuji to řadit přesně tak, jak je to uvedené v příspěvku #11. Všechny ostatní funkce to řadí v tomto pořadí: 01.html 02-01.html 02.html 03.html Kdyby na to existovala nativní php funkce, bylo by vše ok. Já jsem šel cestou reg výrazů a tam jsem pohořel na subvýrazech. Ale když použiji pevnou hloubku názvu souboru, např.: 01.html ... 99-99-99-99-99.html, tedy jakoby 5 úrovní názvu, mohu situaci řešit vlastní sortovací funkcí přes usort: private function cmp($a, $b) { $ma = array(); $mb = array(); preg_match(REGEX, $a, $ma); preg_match(REGEX, $b, $mb); for ($i=1; $i<count($ma); $i++) { if ($ma[$i] != $mb[$i]) return $ma[$i] < $mb[$i] ? -1 : 1; } return 0; } '/^(\\d{2})(?:-(\\d{2}))?(?:-(\\d{2}))?(?:-(\\d{2}))?(?:-(\\d{2}))?\\.phtml$/'
Šlo mi ale od začátku o to, abych nemusel omezovat počet "levelů" v názvu souboru. |
||
peta Profil |
#14 · Zasláno: 28. 1. 2014, 14:53:00
Porovnava i delku retezce. To je to, na co jsem v te moji js verzi upozornoval, ze to tam nemam zabudovane. Muzes udelat vlastni funkci, ktera vyuzije serazeni a,b podle natsort a pak to jeste porovnat na delku retezce a vratit vysledek. Viz, jak jsem to resil s tim JS, taky predavam sortu vlastni funkci.
Tve serazovani mozna bude neco super, ale pro vic polozek to bude pomale a budes zatezovat stroj s php. Jestli to za to stoji? TC zatezuje stroj uzivatele, ne server. |
||
MTF Profil |
#15 · Zasláno: 28. 1. 2014, 14:55:47
peta:
Ok, díky moc za rady.. |
||
Tori Profil |
#16 · Zasláno: 28. 1. 2014, 16:09:45
Dá se to udělat i takhle - reguláry se použijí méněkrát, než kdy byly v řadicí funkci:
$pole = array('01.html', 'A_02.html', '02.html', '02-01.html', '03.html', ); $tmp = array(); foreach ($pole as $name) { $tmp[$name] = preg_replace('~^\D*|\D*$~', '', $name); } asort($tmp); $pole = array_keys($tmp); var_dump($pole); |
||
Časová prodleva: 10 let
|
0