Rozdelenie stringu podla medzier

Programovacie jazyky, rady, poradňa...
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

Zdravim,

Potreboval by som pomoct s jednym algoritom. Mam urcity textovy retazec a dajme tomu, ze potrebujem aby sa zobrazil tak, ze na jednom riadku bude maximalne xy znakov (momentalne je to na 30 znakov). To by nebol problem ale chcem to tak, ze ak na tom 30-tom znaku sa najde znak a nie medzera tak ide naspat ku najblizsej medezere a echne to. Potom nasledne si zapamata, kde skocil a takto pokracuje az do konca retazca.
Neviem, kde robim chybu.Zacne to dobre (prvy riadok) no a potom sa to nejak pokazi a ide to do nekonecneho cyklu. Pravdepodobne problem bude v tejto casti:

Kód: Vybrať všetko

            while($string[($start + $vv)] != " ")
            {
               --$vv;
            } 
Ale netusim ako to dat inak aby sa to spojazdnilo. Tu je cely kod:

Kód: Vybrať všetko

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=windows-1250">
  <meta name="generator" content="PSPad editor, www.pspad.com">
  <title></title>
  <style>
  body {
  font-family: "Lucida Console", "Monaco CE", fixed, monospace;
  
  }
  </style>
<body>
12345678901234567890123456789012345678901234
<br />
<?php 
    
$startString = "Masarykova kolónia bankových úradníkov toto bol oficiálny názov obytného bloku, ktorý podľa projektu. ";

echo $startString;
echo "<br />";

$start = 0;
$finish = strlen($startString);

while($start < $finish)
{
     $string = substr($startString, $start, 30);
    
    if($string[($start + 30)] == " ")
    {
        echo $string;
        $start += 30;
    } else { 
            $vv = 30;
            while($string[($start + $vv)] != " ")
            {
               --$vv;
            }
            
        echo substr($startString, $start, $vv);
        $start += $vv;
    }    
     
    echo "<br />";
}

?>
</body>
</html>
(Tie cisla a font je tam len na to aby sa to lepsie kontolovalo)
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

Kód: Vybrať všetko

<?php
   
$startString = "Masarykova kolónia bankových úradníkov toto bol oficiálny názov obytného bloku, ktorý podľa projektu. ";

echo $startString;
echo "<br />";

$i = $start = 0;
$finish = 30;

$arr = explode(" ",$startString);  //podelim si string po medzerach
while($i < count($arr)){  //kým nevypíšem všetky slová
	$start += strlen($arr[$i]) + 1;  //pripocitam slovo do dlzky (+1 kvoli medzeram medzi slovami)
	if($start < $finish){  //ak sa zmestim do riadku
		echo " ".$arr[$i];  //vypisem slovo
      $i++;   //a idem na dalsie
		} else {
		echo "<br />"; //inak odentrujem
		$start = 0; //a ratam dlzku odznova
		}
}


?>
ak bude $finish menej ako dlžka prvého slova, tak sa ti to aj tak zacyklí. Podmienku aby to nenastalo si budeš buď strážiť (ak to zadávaš iba raz a dostatočne rozumné) alebo si ju dopíš sám (ak to sú vstupy užívateľa)
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

WOW, diki moc, uzasne, ja som sa s tym trapil jak svina :D

//autoeditácia príspevku (23 Apr 2010, 21:22)
Mam problem, ako to mam osetrit ked v texte sa nachadzaju uz aj entre teda znacky <br />? Niekde kde je len text cisty toto slape fajn ale ked niekto zacne entrovat resp. vkladat <br /> znacku, tak to cele pada a netusim ako to osetrit.
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

Záleží ako to ošetriť chceš. Napadajú ma dve varianty:
1) ešte pred nasekaním na medzery to bude nasekané podľa <br />. Potom prejdeš v cykle týmto poľom a ak je tam jedna položka a to reťazec <br /> tak to vypíšeš a dáš continue (ani nemusíš lebo by ti to aj tak vypísalo do riadku a teda odentrovalo ale je efektívnejšie iba odentrovať a skočiť ďalej), inak dáš to čo som ti napísal do zdrojáku (teda podelenie tohto prvku po medzerách..)
2) odstrániť všetky "entre" a previesť ich na medzery. Stačí pred riadok

Kód: Vybrať všetko

$arr = explode(" ",$startString);
daj riadok

Kód: Vybrať všetko

$string=preg_replace('/(<br(\x20)*\/>(\x20)*)+/',' ',$string);
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

dvojka pada lebo ked to uzivatel sam odentruje tak je to prioritne a nemozem mu to prestylovat podla seba. Cize ak on da enter a neprekracuje riadkovy limit tak je to prioritne. Moje <br /> by malo nastupit az potom ako prkrocil tento limit. Jednotke nechapem moc dobre ale ak by to bolo tak ako vravim tak ju skusim.
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

a nerieši náhodou tvoj problém z toho br spraviť slovo? (teda ohraničiť ho medzerami?). Lebo ak dobre chápem, tebe robí prolém slovo<br/>slovo čo vyhodnotí ako jedno slovo a môže to na ňom zamrznúť ak je to dlhšie ako tých 30 znakov. Inak nevidím problém, lebo ak je tam to br tak pri výpise spraví zalomenie a oddelí ti to grafický slová presne tak, ako majú byť. Ak to správne chápem, tak stačí dať

Kód: Vybrať všetko

$startString=preg_replace('/(<br(\x20)*\/>(\x20)*)+/',' <br /> ',$startString);
pred

Kód: Vybrať všetko

$arr = explode(" ",$startString);
Ak to chápem zle, tak ukáž vzorový string ktorý ti robi neplechu
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

Kód: Vybrať všetko

$startString = "Masarykova <br /> kolónia bankových úradníkov <br /> toto bol oficiálny názov obytného bloku, ktorý podľa projektu. ";

$startString = nl2br($startString); // Zmenim /n na HTML tag <br />

$startString=preg_replace('/(<br(\x20)*\/>(\x20)*)+/',' <br /> ',$startString);

// Odstranenie nadbytocnych medzier
$startString = preg_replace("/ {2,}/", " ", $startString);

$i = $start = 0;
$finish = 30;

$arr = explode(" ",$startString);  //podelim si string po medzerach
while($i < count($arr)){  //kým nevypíšem všetky slová
   $start += strlen($arr[$i]) + 1;  //pripocitam slovo do dlzky (+1 kvoli medzeram medzi slovami)
   if($start < $finish){  //ak sa zmestim do riadku
      echo " ".$arr[$i];  //vypisem slovo
      $i++;   //a idem na dalsie
      } else {
      echo "<br />"; //inak odentrujem
      $start = 0; //a ratam dlzku odznova
      }
}
Momentalne mi nevypise prve slovo. V podstate ide o to, ze mam text. Tvoj kod bol dobry pretoze automaticky generoval kde dat enter ak sa jednalo o cisty text. Teraz sa situacia skomplikovala lebo uzivatel moze si sam zadavat enter. Ateda ak si ho zada pred alebo za tym 30-tym znakom tak moj enter neni treba ale zaroven musim rozoznavat ked ho neda a urobit to tak ako povodne. Cize ak ho da on pred 30-tym znakom, ja ho uz nedavam a beriem to ako keby som ho uz dal. Ak ho neda tak ho musim dat.

// Prve slovo vypisuje, som sa pomylil ale v podstate to robi tu chybu ze to dava aj enter od usera a zaroven to <br /> berie ako sucast retazca (co neni) a dava si entre po starom bez ohladu na userove entre
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

začínam sa strácať v tom čo chceš, ale ak to dobre chápem tak takto nejak. Enter dá iba ak je niekde v rozmedzí tých 30 znakov. Ak je na konci, tak ho nedá lebo inač by to odentrovalo dvakrát. Dobre to chápem?

Kód: Vybrať všetko

<?php
   
$startString = "Masarykova <br/> kolónia bankových úradníkov <br/> toto bol oficiálny názov obytného bloku, ktorý podľa projektu. ";

$startString = nl2br($startString); // Zmenim /n na HTML tag <br />

//$startString=preg_replace('/(<br(\x20)*\/>(\x20)*)+/',' <br/> ',$startString);

// Odstranenie nadbytocnych medzier
$startString = preg_replace("/ {2,}/", " ", $startString);



$i = $j = $start = 0;
$finish = 30;
$out = array();  

$arr = explode(" ",$startString);  
while($i < count($arr)){  
   if($start + ($arr[$i] != "<br/>" ? strlen($arr[$i]) : 0) + 1 < $finish){  
	  $out[$j++] = " ".$arr[$i];  
	  if($arr[$i] != "<br/>") $start  += strlen($arr[$i]) + 1;
	  	else $start = 0;
      $i++;   
      } else {
      if($out[$j-1] != "<br/>" && $arr[$i] != "<br/>") $out[$j++] = "<br />"; 
      $start = 0;
      }
}
echo implode(" ",$out);

?>
komentovať sa mi to nechce, snáď tomu budeš rozumieť. Idem spať, ak to nie je ono tak pokračujeme v nedelu :) (zajtra som celý deň odcestovaný)
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa chrono »

Najjednoduchšie (v zmysle, že s tým bude najmenej práce) asi bude dať tú časť, kde sa už delí očistený reťazec do funkcie (alebo do cyklu) a ten vstupný reťazec najskôr rozdeliť pomocou explode na hraniciach \n (alebo <br />) a takto rozdelený reťazec budeš deliť rovnako, ako ho delíš teraz.
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

chrono napísal:Najjednoduchšie (v zmysle, že s tým bude najmenej práce) asi bude dať tú časť, kde sa už delí očistený reťazec do funkcie (alebo do cyklu) a ten vstupný reťazec najskôr rozdeliť pomocou explode na hraniciach \n (alebo <br />) a takto rozdelený reťazec budeš deliť rovnako, ako ho delíš teraz.
nebude, lebo ak to dobre chápem, on potrebuje rozlišovať či je ten enter na konci riadku, alebo medzi. Tie na konci sa vynechávajú (lebo to odentruješ ty) a tie v riadku sa spracujú. Možno len zle chápem, ale toto čo píšeš je ten variant jedna čo som mu navrhoval pár príspevkov vyššie
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa chrono »

Z toho čo píše som pochopil, že presne tú prvú možnosť on potrebuje (ale keďže sa k nej vôbec nevyjadril, možno potrebuje niečo iné a teda som to čo píše vôbec nepochopil). :)
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

Ja tu prvu moznost som nepochopil dobre tak som sa nemohol vyjadrit ci je to to co potrebujem alebo nie, iba som opisal situalciu aby to bolo jasnejsie co potrebujem. Audiotrackov kod si zajtra s cerstvou hlavou pozriem a otestujem a potom sa ku tomu vyjadrim, dnes mi to uz nemysli...
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa chrono »

Tá prvá možnosť funguje tak, že sa ten vstupný reťazec najskôr rozdelí podľa toho, kde zadal koniec riadku používateľ. Potom sa tie reťazce prípadne ešte rozdelia na 30 znakové úseky (ak sú tam časti, ktoré sú dlhšie, ako potrebuješ).
Snacker
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 362
Registrovaný: 08 jún 2009, 22:42
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa Snacker »

Dik za vysletlenie, ta prva moznost ide presne ako ma...

Dik audiotrack za perfis kod, mas to u mna :)

//autoeditácia príspevku (30 Apr 2010, 13:17)
Ako by som to mal osetrit ked $arr[$i] je vacsie ako $finish = 30; cize jedno slovo na riadok je vacsie ako riadok. V momealnej situacii sa to nejak zasekne resp. vycerpa sa operacna pamat.
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: Rozdelenie stringu podla medzier

Príspevok od používateľa audiotrack »

reťazec je tiež len pole znakov, takže ti stačí $arr[$i] podobným spôsobom rozdeliť na prvky (len tu nebudeš deliť podľa znaku ale podľa dlžky)
Napísať odpoveď