Preg_split treba preskočiti ono što je unutar zagrada

Koristim preg_split da prelomim rečenice (ako naiđe na točku, upitnik ili uskličnik) i uzmem prvu rečenicu. Što bi trebalo napraviti da se preg_split ne obazira na nešto, konkretno da se preskoči ono što se nalazi unutar zagrada?

$lorem = ‘lorem ipsum (this. needs to be skipped.) something something. huehue lorem. again lorem’;
$text = preg_split(’/(.|?|!)(\s)/’, $lorem );

Ono što se nalazi unutar zagrada mi je i dalje potrebno, samo ne želim da se rečenice prelamaju prema tim točkama

Evo, stavio sam prvu rečenicu tvoju i radi dobro http://regexr.com/3ca57

…no nisam išao baš u dubinu, neznam kako će se ponašati kod rekurzivnih zagrada i šta ja znam kakvih caka. (Možda ti netreba da radi na neznam kakvim kombinacijama, pa ti ovo bude dobro… možda ti ideja posluži)

Objašnjenje izraza: ((\(.*\))|.)*?(\.|\?|!)

kojeg ću semantički pojednostavniti, znači imaš zapravo (a|b)*?c

a=(\(.*\)) -> selekcija mora započinjati sa zagradom, završavati sa zagradom…između smije biti što god, koliko god puta
b= selekcija može biti što god

(a|b)* -> a ili be se mogu ponavljati koliko god puta

c= (\.|\?|!) -> izraz mora završiti sa c, što je popis tvojih krajeva rečenice: uskličnik, točka, upitnik

i još primjeti *? , regularni izrazi su po prirordi greedy, ili ti ga pohlepni …i da su napravili match cijelog zadanog tekst, rezultat bi odgovarao upitu. jer (a|b) mogu “progutati” zapravo sve do zadnje točke. No kad se na metodu * zakači upitnik (?) …onda ta zvjezdica više nije greedy nego lazy…i uzet će minimalno koliko treba da konačni matching odgovara zadanom upitu.

Hm nije to to, rezultat koji dobim su dva prazna stringa, a treći sadrži zadnju rečenicu, a ni na regexru ne radi :slight_smile: možda se nismo skužili :smile:

$text = ‘Ovaj proizvod (sinonim proizvoda koji može. imati jednu ili . više točka) je nešto bla bla. Najjači je proizvod ikad. Predobro. Proizveden je 1956. godine. ‘;
$text2 = preg_split(’/(((.))|.)?(.|?|!)/’, $text);
var_dump($text2);

Gornja rečenica bi trebala u konačnici biti rastavljena ovako

  1. Ovaj proizvod (sinonim proizvoda koji može. imati jednu ili . više točka) je nešto bla bla.
  2. Najjači je proizvod ikad.
  3. Proizveden je 1956. godine.

Znači samo prelamanje rečenica poslije točka (upitnik i uskličnik mi nisu bitni al hajd, reda radi) uz zanemarivanje sadržaja između obične zagrade, a sad mi je palo na pamet da bi bilo dobro i da zanemari ako iza broja dolazi točka (zbog godine).

Ne kužim zašto kažeš da ne radi na regexru, kad radi :smile: Isto tako će raditi i ako kopiraš tamo tu svoju novu rečenicu.
Regexr ti selektira sve dostupne selekcije…pa ti se možda čini da je krivo selektirao. Ako dođeš mišom povrh selekcije, vidjet ćeš što sve spada u tu selekciju. Isto tako možeš bolje pogledati, pa ćeš vidjeti i mali razmak između odvojenih selekcija.
I tamo će selektirati upravo kao što tražiš ovdje, samo će ti razbiti rečenicu i kod “1956.” zbog točke nakon broja.

Ti si se tek sad sjetio da ti može doći točka nakon broja, bojim se da se onda još puno toga nisi sjetio. …jer imaš kratice koje završavaju s točkom, imaš … 3 točkice koje češće označavaju zarez nego točku. Imaš new line koji koji često asocira na novu rečenicu, iako prethodna nije dobila točku.

Fakat kvalitetno rastavljanje na rečenice nije trivijalno. (Pogotovo ako su ti inputi došli od usera koji barataju eto gramatikom internet doba, gdje im točka malo toga predstavlja u životu xd)

Znači, u prvu ruku moraš biti na čisto sa sobom koliko kvalitetno trebaš razbijati rečenice, i kakvi ti sve inputi mogu naići?
Ako je samo do broja, onda neće biti takav problem i to dodati… smislim nešto i za to…
…a ovo što ti trenutno ne radi:

  1. prvo uvidi da na regexru radi (prema tvom prvotnom zahtjevu)
  2. nađi način kako da to preneseš u preg_split. (možda postoji minorna razlika u sintaksi, iako ne vjerujem…ali nisam siguran oko toga…)

Evo ga, sad više neće rastavljati kod točke koja dolazi nakon broja: http://regexr.com/3ca5d

P.S. možda sam skužio zašto ti nije radio. Probaj s ovom verzijom: http://regexr.com/3ca5g
Naime…ova prvotna verzija nije tražila rezultat u različitim redovima…nego je očekivala da pojedina selekcija mora postojati samo u jednoj liniji. Tvoji inputi možda stižu u više linija…pa je možda to bila caka…

Btw…evo ti već nove iznimke, što ako ti naiđe rečenica:
Mali perica, čim je došao kući otvorio je stranicu webmajstori.com na svom računalu.

Opet imaš točku uljeza xd.

EDIT2: ajooj, znam zašto ti ne radi xd. Ja ti slažem izraze koji selektiraju cijelu rečenicu…a tvoj split onda splita tako da mu je separator cijela rečenica xd. Naravno da ni s jedne strane rečenice neće onda ostati ništa, hehe.

Možeš to napraviti i sa preg_match:

$matches=array();
$text = 'Ovaj proizvod (sinonim proizvoda koji može. imati jednu ili . više točka) je nešto bla bla. Najjači je proizvod ikad. Predobro. Proizveden je 1956. godine. ';
preg_match('/((\(.*\))|.)*?(\.|\?|!)/', $text, $matches);
echo 'first sentence: '.$matches[0];

možeš dohvatiti i sve rečenice, samo koristiš preg_match_all()

1 Like

Isuse kako je to meni komplicirano. Vidim da sad regexr radi, odabere sve, međutim… onda ne kužim kako funkcionira preg_split jer mi var_dump daje prazne stringove. Di su nestale rečenice? :smile:

Da, znam da može biti puno caka s točkom no meni treba samo izbjeći točke koje su unutar zagrade jer rečenice tako specifične konstrukcije, a ovo s točkom poslije godine dobro dođe ako zatreba.

Edit: ah da, ok, idem probat

Objasnio sam ti u zadnjem postu :wink: …mogu i detaljnije:
Preg split razbija po zadanom izrazu. Ako je taj izraz recimo samo točka “.”,
sljedeći string: "ana.pero.ivo"
će razbijen izgledati 1-> ana 2->pero 3->ivo

ako bi recimo izraz razbijanja bio “pero” …onda bi isti gornji string razbijen izgledao:

1-> ana.
2->.ivo
…pero nam je nestao, jer smo po njemu razbili.
E sad, gore u tvom primjeru kod rastavljanja rečenica je sve nestalo, jer smo mi razbijali po cijelim rečenicama :smiley:

Preg_match radi super. Puno hvala :slight_smile:

Nema na čem :wink:
Nemoj još zaboraviti staviti unutra ovaj zadnji izraz odavde: http://regexr.com/3ca5g (taj ti neće razbijati nakon broja i gledati će ti u multiline inpute)

1 Like