Autor | Zpráva | ||
---|---|---|---|
danhill Profil |
#1 · Zasláno: 4. 5. 2016, 20:41:55
Ahoj,
opět válčím s reg. výrazy a nedaří se mi. Mám různé typy zápisů na vstupu. Konkrétně tyto: Multi-cache Multi MultiCache Multi-Cache Multi cache Multi Cache a stejné možnosti u mnoho dalších Mystery-cache Mystery MysteryCache . . . dále Wherigo-cache atd atd Pomocí regulárního výrazu potřebuji vytáhnout vždy to první slovo. Nejlepší by bylo to první slovo definovat, respektive tak aby se dalo kdyžtak přidat další první slovo a aby nenastal problém v momentě,kdy by první slovo také obsahovalo c nebo C Ale to není podmínkou, mě to nechodí ani bez definování prvního slova. Prosím o pomoc s tímto reg. výrazem. Zkouším třeba (.*?)[ \-\C\c]+(.*?) Moc děkuji. |
||
juriad Profil |
#2 · Zasláno: 4. 5. 2016, 20:52:32
Pokud ty výrazy máš někde samostatně a nepotřebuješ je hledat v textu, asi bych na to šel jednodušeji:
<?php foreach (file('f', FILE_IGNORE_NEW_LINES) as $text) { # převeď všechny znaky na malé, zahoď slovo cache, zahoď vše co není písmeno $cache = preg_replace('/[^a-z]/', '', preg_replace('/cache/', '', strtolower($text))); echo "$text: $cache\n"; } |
||
danhill Profil |
Ne ne, právě že je hledám v textu:
Mám něco takového: preg_match_all("'<img src=\"/images/WptTypes/(.*?)\" alt=\"(.*?)\"'si", $htmlcache, $match); foreach($match[2] as $val) { echo $val."<br>"; } Kde právě v alt= je to požadované sousloví.A první písmeno bych právě velké naopak potřeboval ... |
||
juriad Profil |
Jelikož máš oblast vyhrazenou uvozovkami, můžeš použít:
preg_match_all('#<img src="/images/WptTypes/(.*?)" alt="([a-z]*)[ -]?(?:cache)?"#si', $htmlcache, $match); Pozn. Regulární výrazy vždy zapisuj mezi apostrofy, ušetříš si escapování a pro ohraničení můžeš použít jakýkoli vhodný znak, často se používají: /~# .
To velké písmeno pomocí regexů v PHP neuděláš. Ale to ti nevadí: echo ucfirst($val), "<br>"; |
||
danhill Profil |
wooow ... Opět smekám ... Děkuji pěkně ...
Nádhera ... A já se s tím s* tři hodiny. JS a regexy, to je moje smrt prostě ... Jen doplňující otázka pro mou zvědavost, pokud bych oblast neměl vyhrazenou uvozovkami, kdybych například hledal to stejné mezi html tagy <h1>Multi-cache</h1> tak to v praxi znamená co?
|
||
danhill Profil |
Tak se to schválně zkouším pochopit,ale prostě ne ...
Ještě poprosím o pomoc ... V tom escapování úplně jako logiku nevidím. Přitom mi to příjde napsané stejně jako příklad výše,jen tam nejsou ty uvozovky, to je pravda ... preg_match_all('#<li class="li__cache-type">([a-z]*)[ -]?(?:cache)?</li>#si', $htmlcache, $match); |
||
juriad Profil |
#7 · Zasláno: 5. 5. 2016, 11:21:58
Ano, je to velice podobné.
Escapování. Vidíš, že teď v tom regexu není jediné zpětné lomítko a je o dost čitelnější. Apostrofy jsou vhodnější, protože tam existují jen dvě escape sekvence: \\ a \'. Ve většině případů bude stačit napsat méně zpětných lomítek. Ohledně toho ohrazení uvozovkami. Kdybys hledal ve volném textu, tak ti to najde třeba spojení „dobra cache“, což asi nechceš. Právě to, že je to uvnitř atributu (nebo uvnitř položky seznamu, to je jedno) zajistí, že to omylem nenajde něco, co není typ cache. |
||
danhill Profil |
#8 · Zasláno: 5. 5. 2016, 12:32:22
No ale takto nefunguje to ...
To s těmi křížky jako chápu, že pak nemusím escapovat pomocí \ ,určitě je to přehlednější, ale stejně mi někde v případě vyhledávání mezi html tagy nějaký escape chybí ... Podle mě konkrétně minimálně v </li> ,ale ještě někde,kde to nevidím ... :( |
||
juriad Profil |
danhill:
Zpracovávat HTML pomocí regexů je ošidné, protože to klidně může obsahovat spoustu mezer a odřádkování, se kterými nepočítáš. Dodej ukázku přesného HTML, které zpracováváš, případně pošli odkaz na stránku, odkud to pochází. Ne, nikde nic nechybí, regex je v pořádku, jen mu dáváš jiné vstupy, než očekává. |
||
danhill Profil |
#10 · Zasláno: 5. 5. 2016, 12:44:47
|
||
juriad Profil |
#11 · Zasláno: 5. 5. 2016, 12:50:46
Na odkázané stránce nic takového není. Pomoci JS přesměrovává na www.geocaching.com/geocache/GC1ZYF5_v-ozvene, na ní (pokud je uživatel nepřihlášený) se nachází:
<li class="li__cache-type"> Multi-cache </li> Použij regex: preg_match_all('#<li class="li__cache-type">\s*([a-z]*)[ -]?(?:cache)?\s*</li>#si', $htmlcache, $match); |
||
TomášK Profil |
#12 · Zasláno: 5. 5. 2016, 13:17:19
A určitě to chceš dělat regulárními výrazy?
stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags simplehtmldom.sourceforge.net (nemám vyzkoušené, nepoužívám php) OT: Není tu někde diskuze o používání regulárních výrazů na parsování html? Čekal bych, že ve FAQ bude, ať to lidi nedělají, ale co jsem zaznamenal, tak se nad tím nikdo nepozastavuje. |
||
danhill Profil |
ono to tam přesměruje,ano ...
No jasně whitespace ... že mi to nedošllo ... Děkuji, už to chápu. Teda pro tento případ to chápu,obávám se,že až budu hledat něco jiného,zase to bude porod :) TomášK: Nevím o jiné možnosti jak to udělat :( |
||
juriad Profil |
#14 · Zasláno: 5. 5. 2016, 13:23:52
TomášK:
Zrovna v případě, kdy se jedná o jeden jediný tag to regexy jde řešit ještě pěkně. Použít knihovnu pro parsování HTML na celou stránku by byl overkill. Kdyby už nějak dokázal vyříznout jen relevantní část, může ji zpracovat rovnou pomocí regexů. danhill: Výborně. Neboj se znovu zeptat. |
||
TomášK Profil |
Alternativa je použít DOM parrser. Ten druhý odkaz je knihovna pro parsování DOM, pak by mohlo jít něco jako
$html = file_get_html(' www.geocaching.com/geocache/GC1ZYF5_v-ozvene'); echo $html->find('li.li__cache', 0)->innertext // Multi-cache Ale jak jsem psal, v php to vyzkoušené nemám, je to první, co jsem našel na googlu. Možná jsou lepší knihovny, případně i něco přímo v php. juriad Pokud to potřebuje externí závislost, můžou být regexpy rychlé řešení. Ale jinak výhody nevidím - jsou náchylnější na chyby, méně přehledné, hůř se v tom ošetřují třeba chybějící uvozovky okolo hodnot apod. Možná budou o fous rychlejší, ale i ten DOM parser to naparsuje rychleji než se to stáhne. |
||
Časová prodleva: 4 dny
|
|||
danhill Profil |
Ještě malá drobnost.
preg_match('#<img src="/images/WptTypes/(.*?)" alt="([a-z]*)[ -]?(?:cache|geocache|hybrid)?"#si', $htmlcache, $match); V momentě,kdy jsou slova odděleny pomlčkou nebo mezerou,tak to samozřejmě šlape. To má za úkol [ -]
Ale problém nastane,když mám napsáno MultiCache bez jakéhokoli oddělovače. Tak se chci zeptat,jestli se do toho regexu nedalo dopsat ještě aby zahodil slovo cache,pokud tam je a pokud není oddělovač mezera nebo -. Zkoušel jsem třeba preg_match('#<img src="/images/WptTypes/(.*?)" alt="([a-z]*)(cache)|[ -]?(?:cache|geocache|hybrid)?"#si', $htmlcache, $match); Děkuji moc. |
||
juriad Profil |
danhill:
Ok, stačí přidat otazník: preg_match('#<img src="/images/WptTypes/(.*?)" alt="([a-z]*?)[ -]?(?:cache|geocache|hybrid)?"#si', $htmlcache, $match); |
||
danhill Profil |
#18 · Zasláno: 9. 5. 2016, 23:37:54
Děkuji moc. Funguje bezvadně ...
|
||
Časová prodleva: 8 let
|
0