Експлодване на текст

cHuBakA

Registered
Здравейте. Как може да стане? Идеята е експлодването да е само след дума - равна или по-голяма от 5 букви с точка?

Пример :
Едно две шест. Едно две три четири. Едно две пет. Едно две две.

Резултат :
=> Едно две шест. Едно две три четири.
=> Едно две пет. Едно две две.
 
Код:
<?php
$string = 'Едно две шест. Едно две три четири. Едно две пет. Едно две две.';
$separator = '.';
$sentences = explode($separator, $string);
foreach ($sentences as $key => $sentence) {
  if (mb_strlen(end(explode(' ', $sentence))) >= 5) {
    $array['clear'] = str_replace($sentence.$separator, '', $string);
    $array['removed'][] = $sentence.$separator;
  }
}

echo "<pre>";
var_dump($array);
 
uphero Благодаря за примера. Проблема е че след първото изречение ми вади null. Не знам защо. Аз сглобих това работи и дели изречението през три изречения, обаче го дели само на точка . Чудя се как може да стане да е с горното условие. Да дели само ако преди точката думата е равна или по-голяма от 5 букви?? Демек ако преди точката думата е по-малка от 5 букви да не го дели?

Код:
$sentences = explode(". ", $string);
$new_string = "";
$j = 1;
foreach($sentences as $sentences_el) {
    $new_string .= $sentences_el.".";
    if($j % 3 == 0) {
        $new_string .= "<br><br>";
    }
    $j++;
}
echo $new_string ;
 
Друго решение

Код:
$str = "Едно две шест. Едно две три четири. Едно две пет. Едно две две.";

$res = mb_split('(?<=\S{5,}\.\s)', $str);

print_r($res);
 
djman каза:
Друго решение

Код:
$str = "Едно две шест. Едно две три четири. Едно две пет. Едно две две.";

$res = mb_split('(?<=\S{5,}\.\s)', $str);

print_r($res);
връща фалсе, иначе ме уби с тоя код :D
Всичко на всичко един ред
 
uphero каза:
връща фалсе, иначе ме уби с тоя код :D
Всичко на всичко един ред

Как така, при мен си връща два елемента (php 8.0.6 cli) -

Array
(
[0] => Едно две шест. Едно две три четири.
[1] => Едно две пет. Едно две две.
)

Вярно че всички без последния ще трябва да минат през rtrim.
 
Интересно, явно "variable-length lookbehind" не работи в PHP, освен когато работи :think:

Ето още един вариант...

Код:
$str = "Едно две шест. Едно две три четири. Едно две пет. Едно две две.";

preg_match_all("/(\S.+\b\S{5,}\.)|(\S.+$)/uU", $str, $res, PREG_SET_ORDER);
$res = array_map('current', $res);

var_dump($res);

array(2) {
[0]=>
string(62) "Едно две шест. Едно две три четири."
[1]=>
string(47) "Едно две пет. Едно две две."
}
 
djman каза:
Интересно, явно "variable-length lookbehind" не работи в PHP, освен когато работи :think:

Ето още един вариант...

Код:
$str = "Едно две шест. Едно две три четири. Едно две пет. Едно две две.";

preg_match_all("/(\S.+\b\S{5,}\.)|(\S.+$)/uU", $str, $res, PREG_SET_ORDER);
$res = array_map('current', $res);

var_dump($res);

array(2) {
[0]=>
string(62) "Едно две шест. Едно две три четири."
[1]=>
string(47) "Едно две пет. Едно две две."
}
djman Интересно всички функции работят от php4 нагоре, но реално не работи. Дали има някъде грешка, която не виждам, как ли не го пробвам, но не успявам да го подкарам
 
cHuBakA каза:
djman каза:
Интересно, явно "variable-length lookbehind" не работи в PHP, освен когато работи :think:

Ето още един вариант...

Код:
$str = "Едно две шест. Едно две три четири. Едно две пет. Едно две две.";

preg_match_all("/(\S.+\b\S{5,}\.)|(\S.+$)/uU", $str, $res, PREG_SET_ORDER);
$res = array_map('current', $res);

var_dump($res);

array(2) {
[0]=>
string(62) "Едно две шест. Едно две три четири."
[1]=>
string(47) "Едно две пет. Едно две две."
}
djman Интересно всички функции работят от php4 нагоре, но реално не работи. Дали има някъде грешка, която не виждам, как ли не го пробвам, но не успявам да го подкарам

http://sandbox.onlinephpfunctions.com/code/a17d99d6bd9bd3d04d7b9d54118c982ae8a765d1

Кода си работи на 5.6. Ако не работи при теб, значи там където го използваш се чупи. Дай повече код, ако трябва.
 
Благодаря. Изглежда кода работи супер като го тествам в onlinephpfunctions.com.
А как може да се извика целия текста като включи </br> при разделянето ?


Едно две шест. Едно две три четири.
<br>
Едно две шест. Едно две три четири.
<br>
Едно две шест. Едно две три четири.
<br>
 
Благодаря много!!!!!!!!

След 4 дни чудене и проби успях да разбера защо кода не работеше. Проблема се оказа , в кирилицата. С латинските букви работи супер. Обаче не откривам начин да тръгне на кирилица :| preg_match_all дали работи с кирилица??
 
cHuBakA каза:
Благодаря много!!!!!!!!

След 4 дни чудене и проби успях да разбера защо кода не работеше. Проблема се оказа , в кирилицата. С латинските букви работи супер. Обаче не откривам начин да тръгне на кирилица :| preg_match_all дали работи с кирилица??

Кодировката трябва да е UTF8. Предполагам, че вадиш текста от базата данни? Увери се, че излиза с правилна кодировка. Миксиране между cp1251 и utf8 ще ти навлече и други проблеми, за това трябва да нормализираш нещата.
 
Между другото, този regex хваща и малко по-особени случаи (думата с точка е без нищо преди нея, или е в началото, или целия стринг е само един символ):

Код:
$str = "Четири. Едно две шест. Едно две три четири. Аааааа. ааааааа Четири. Едно две пет. Едно две две.";

preg_match_all("/\S.*\S{5,}\.|\S.*$/uU", $str, $res, PREG_SET_ORDER);


array(5) {
[0]=>
string(13) "Четири."
[1]=>
string(62) "Едно две шест. Едно две три четири."
[2]=>
string(13) "Аааааа."
[3]=>
string(28) "ааааааа Четири."
[4]=>
string(47) "Едно две пет. Едно две две."
}
 
Благодаря Ви много !!!! Мисля че схванах принципа.

Имам и въпрос относно допълнение. Възможно ли е да се добави и второ условие - ако има текст в кавички да НЕ го дели??
Всъщност това възможно ли е във един regex ?
 
Да, пробвай да добавиш едно ".+"| най-отпред: ".+"|\S{5,}\.|\S.*\S{5,}\.|\S.*$
Това цялото нещо работи защото PHP поддържа U (Ungreedy) modifier.
 
djman каза:
Да, пробвай да добавиш едно ".+"| най-отпред: ".+"|\S{5,}\.|\S.*\S{5,}\.|\S.*$
Това цялото нещо работи защото PHP поддържа U (Ungreedy) modifier.

А възможно ли е по същия начини да се добави и за число или знаци? Забелязах че например 5. или %. също го дели грешно?
 
\S по принцип означава "non-whitespace", има два варианта да го замениш:

- със символи, които очакваш: [а-яА-Я], но не знам дали това работи така, както a-zA-Z, например
- със символи, които не искаш да се взимат в предвид: [^.\d\s] - бих предпочел този вариант

Става дума за \S{5,}, другите са там за да не трябва да се вика trim после.
 
Благодаря МНОГО !!!!!
Извинявам се за всички тези въпроси. Работи супер , дори други експерименти опитах но това с кавичките не знам защо не се получава.
".+"| опитах да го заменя и с ".* "| и не става.

Изречението ако е - ---- "Здравей, как си." ---- Резултата е:

"Здравей, как си.

"

====

Също и ако изречението е ---- "Здравей, как си", къде си? ------ Резултата е:

"Здравей, как си"

, къде си?


====



Също и ако изречението е ------ "Здравей. Как си" ------ Резултата е:

"Здравей.

Как си"


====

Идеята е просто ако има кавички текста между кавичките да не го разделя
 

Горе