ugrás a tartalomhoz

Szöveget tömbbé, írásjelek kihagyásával, új sorokkal

vtsoftware · 2012. Júl. 16. (H), 14.33
Üdvözlet mindenkinek!

Egy szövegben - furcsa módon - ugyebár vesszők, pontok, stb... írásjelek vannak.
Minden szót
<span class="cmenu">_SZÓ_</span>
formára kellene alakítanom.
A gond az, explode-t használva, hogy ha a szó mellett van egy írásjel akkor az a span-on belülre kerül.
<span class="cmenu">részünk,</span>
Hogyan, milyen módon lehet megoldani hogy az írásjel a span-on kívülre kerüljön?

Ezen kívül a gondom az új sor, a \n.
Valamiért az entereket nem veszi figyelembe, így van hogy a következőt kapom:
<span class="cmenu">bizonyult.<br>
<br>
Május</span>
A következő kóddal szenvedek.
$str=str_replace('<br />', '<br>', nl2br($str));
$str=explode(' ', $str);

foreach ($str as $s) {
  echo '<span class="cmenu">'.$s.'</span> ';
}
- Tudom nem egy agysebészet', de nem jut eszembe más megoldás...

Előre is köszönöm a segítséget
 
1

preg_replace

complex857 · 2012. Júl. 16. (H), 15.25
Én így csinálnám:
$text = "szo0, szo1, szo3. \n Alma torta, kijelentem, hogy recece...";
$text = preg_replace('/(?:^|$|\b)(\w+)(?:\b|$|^)/simu', '<span class="cmenu">$1</span>', $text);
ez a kimenet:
<span class="cmenu">szo0</span>, <span class="cmenu">szo1</span>, <span class="cmenu">szo3</span>. 
 <span class="cmenu">Alma</span> <span class="cmenu">torta</span>, <span class="cmenu">kijelentem</span>, <span class="cmenu">hogy</span> <span class="cmenu">recece</span>...
2

Ezer köszönet

vtsoftware · 2012. Júl. 16. (H), 15.31
Nagyon köszönöm... sejtettem hogy a regexp megoldás, de ehhez szinte semmit sem konyítok, csak alapszinten.

Az u flag nem kellett, mert nem UTF8 szövegen alkalmazom...

De tényleg nagyon köszönöm...
3

Van egyfajta gond vele...

vtsoftware · 2012. Júl. 16. (H), 23.13
Helló

Tényleg nagyon hálás vagyok... de valamiért nem jó a dolog.
Elsőre mikor a saját gépemen kipróbáltam rendesen működött, ezért is gondoltam hogy jó lett.

Viszont mikor feltettem az éles oldalra, valamiért hülyeségeket csinál.
A lényeg hogy az oldal jQuery-vel ajax lekéréssel átalakítja a szöveget hogy a szavak <span>-ban legyenek.
Mivel így a php "UTF-8"-ban kapja meg a szöveget megbolondul.
"iconv"-al "ISO-8859-2"-t csinálok az "UTF-8"-ből, de ha a szöveget így engedem rá a "preg_replace"-re, akkor nem úgy működik ahogy kellene, mert az ékezetes kimaradnak a span-ból.
<span class="cmenu">Micsoda</span> <span class="cmenu">j</span>ó <span class="cmenu">kis</span> <span class="cmenu">sz</span>ö<span class="cmenu">sszenet</span>. <span class="cmenu">Az</span> é<span class="cmenu">n</span> <span class="cmenu">n</span>é<span class="cmenu">nik</span>é<span class="cmenu">m</span>.
Őszinte leszek. Mivel nem tudom hogy működik a reg. kifejezés amit adtál, nem tudom hogy tudok alakítani rajta.
Szerinted mit lehet csinálni neki?

Nagyon köszönöm...
4

Minden utf-8

Pepita · 2012. Júl. 17. (K), 03.48
Először is a php kódodat is mentsd utf-8 kódolással, nem szabad "megbolondulnia" ilyen szövegtől.

Aztán vannak más függvények is: Multibyte String Functions.

Ha nem megy a regexp, előbb tanulj bele, vagy oldd meg több replace-el, stb., nem jó, ha úgy használsz fel bármilyen kódot, hogy nem érted mit csinál.

Aztán ne csodálkozz, hogy nem műxik utf-8-al, korábbi tevékenységed:
Az u flag nem kellett, mert nem UTF8 szövegen alkalmazom...
5

iso-8859-2

complex857 · 2012. Júl. 17. (K), 09.22
Hosszú távon jobban jársz ha mindent utf-8 -ban van, mindenesetre feltételezve, hogy a forrás fileod iso-8859-2 -vel van elmentve, ennek működnie kéne:
$wordchars = 'a-zA-Z0-9íöüóőúűéáÍÖÜÓŐÚŰÉÁ';
$word_boundary = '(?:[^'.$wordchars.']|$|^)?';
$pattern = '/'.$word_boundary.'(['.$wordchars.']+)'.$word_boundary.'/m';
$text = "árvíztűrő, tükörfúrógép\n ÁRVÍZTŰRŐ, TÜKÖRFÚRÓGÉP\n";
$text = preg_replace($pattern, '<span class="cmenu">$1</span>', $text);
6

Próba nélkül semmit...

vtsoftware · 2012. Júl. 17. (K), 14.20
"Pepita": Nem írok ide semmit amiről nem bizonyosodok meg...
Kipróbáltam az u flag nélkül is, és avval is.
Ha megadtam, üres szöveget kaptam, ha kivettem visszaadta a szöveget, csak hibásan.
A jQuery ajax karakterkódolását pedig ha szeretném sem lehetne az utf8-tól eltántorítani.
(Ha lehetne is megnéztem a html parancsokat...
POST / HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
---
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
...UTF8 minden..., ezért sem értem a dolog miért nem működik)

Az egész oldalt átírtam UTF-8-ba.
Minden utf8, nem hagytam ki semmit ez biztos. (kivéve egy tinymce-t kell még valahogy átírnom hogy kezelje ne kérdőjelezze az ékezetes betűt, de annak nincs ide köze)

"complex857":
A kód a következő:
$text="Árvizet tűrő, víz bele nem megy, de fúr. \n Tükröt fúr a tükörfúrógép.";
$wordchars = 'a-zA-Z0-9íöüóőúűéáÍÖÜÓŐÚŰÉÁ';
$word_boundary = '(?:[^'.$wordchars.']|$|^)?';
$pattern = '/'.$word_boundary.'(['.$wordchars.']+)'.$word_boundary.'/m';
$text = preg_replace($pattern, '<span class="cmenu">$1</span>', $text);
echo $text;
Ezt adja vissza: "ÁrvizettűrővízbelenemmegydefúrTükrötfúratükörfúrógép"
Mint fentebb írtam, minden utf8, az ajax, a fájl, az oldal... minden és mégis.

Köszönet...
7

phpinfo

complex857 · 2012. Júl. 17. (K), 14.51
Nálam az eredeti kódra (/u -val) akkor ad üres stringet, ha a forrás filet latin2 -kent mentem el, vagy ha kívülről nem utf-8 inputot küldök neki. Utf-8 inputtal (igy forrás file encoding nem számít) terminálon ez így néz ki nálam:

$ echo $LANG
en_US.utf8
$ echo "öüó. őúű, éá\nÖÜÓŐÚŰÉÁíÍ" | php -r 'print preg_replace("/(?:^|$|\b)(\w+)(?:\b|$|^)/simu", "<span class=\"cmenu\">$1</span>", file_get_contents("php://stdin"))."\n";'
<span class="cmenu">öüó</span>. <span class="cmenu">őúű</span>, <span class="cmenu">éá</span>\<span class="cmenu">nÖÜÓŐÚŰÉÁíÍ</span>
Mint irtad a saját gépeden jól is müködött, csak a végleges helyén nem, érdemes lehet átfutni két site phpinfo() -ja közötti külömbségeket.

További ötletként elsőre beszúrnék egy:
mb_internal_encoding('UTF-8');
sort.
Beérkező adatok ellenőrzésére/átalakítására, megnézném mit mond rá mb_detect_encoding(), esetleg átküldeném mb_convert_encoding() -on.
8

Biztos utf8

vtsoftware · 2012. Júl. 17. (K), 15.06
Az mb_detect_encoding szerint utf8-at kap.
Milyen különbségre lennél kíváncsi a két gép phpinfojában?

A kód:
<?php
header("Content-type: text/html; charset=UTF-8");
mb_internal_encoding('UTF-8');

$text = "öüó. őúű, éá\nÖÜÓŐÚŰÉÁíÍ";
$encoding = mb_detect_encoding($text);
$text = mb_convert_encoding($text, 'UTF-8', $encoding);
$text = preg_replace("/(?:^|$|\b)(\w+)(?:\b|$|^)/simu", "<span class=\"cmenu\">$1</span>", $text);
echo $encoding.'<br>'.$text;
?>
Az eredmény:
UTF-8
öüó. őúű, éá
ÖÜÓŐÚŰÉÁíÍ
9

Ami megviccelhet és phpinfo

complex857 · 2012. Júl. 17. (K), 15.34
Ami megviccelhet és phpinfo -ból kiderülhet az mbstring.http_input, mbstring.http_output, mbstring.encoding_translation -al együtt de ezeket nem szokták piszkálni.

Más szerveres perverzió lehet még, hogy a PCRE extensiont utf-8 support nélkül fordították. Ilyenkor warningot kéne dobnia amiben tájékoztat erről, éles szerveren lehet ezek csak logba gyűlnek.

A fenti kódpélda utf-8 fileként az én gépemen (php-5.4.4-4.fc17.i686) úgy müködik ahogy az elvárható tőle, tudom, hogy roppant bután fog hangzani, de ha bongészőben nézed a kimenetet akkor ugye a forrást nézed és nem a sima html kimenetet (kezdek kifogyni az ötletekből :-P)
10

MbString, pass...

vtsoftware · 2012. Júl. 17. (K), 16.02
Hát az mbstring.http_in/output nálam is és a szerveren is "pass" a local és a master is. (A phpinfo oldalon a böngészőben az utf szó keresve sincs...)

Az mbstring beállításai nálam és a szerveren teljesen egyeznek.
A PCRE a szerveren 7.8-as nálam 7.6-os.

A logban nincs hibaüzenet ami ilyen hibára utalna.

Avval pedig hogy a DOM-ot "módosítgatom" tisztában vagyok ;)
11

Azt hiszem sikerült...

vtsoftware · 2012. Júl. 17. (K), 21.30
Nem tudom, még ki kell próbálni, de lehet hogy sikerült.
Egy része tér el a Te kódodtól, de arra épül ;)
Nagyon hálás is vagyok érte, köszönöm hogy rám pazaroltad az időd.

Íme a kód:
$text = $_POST['string'];
$text = explode(' ', $text);
foreach ($text as $word) {
  echo preg_replace("/(?:^|$|\b)([a-zA-Z0-9öÖüÜóÓőŐúÚéÉáÁűŰíÍ]+)(?:\b|$|^)/simu", '<span class="cmenu">$1</span>', $word).' ';
}
Az volt a baj az előzőekben hogy vagy az ékezetes betűket nem tette span-ba - mintegy átugrotta őket - vagy pedig a szóközt hagyta ki...
Aztán jutott eszembe, ha szavanként nézem át, akkor utána teszek egy szóközt és meg is van oldva a probléma...

Mégegyszer nagyon köszönöm...
12

Bár már megoldódott,

Pepita · 2012. Júl. 17. (K), 23.26
mégis hozzátenném: érdemes ránézni a default_charset-re is. Jártam már úgy, hogy a szerveren be volt állítva ISO 8859-1-re, addig nem lett jó a kimenetem, míg be nem állítottam. (Értsd: content-type... hatástalan volt a HTML-ben, mert ezt előtte küldi header-ként.)