Вывести n строк из файла.

1 234
S
На сайте с 13.10.2014
Offline
171
#21
SeVlad #:

Да, кстати. Этот момент я упустил (а ещё троеточия ;) ).

Мало того, есть ещё комбинации вопроса с восклицанием. (?!)
Правила русского языка допускают также три восклицательных знака (!!!)
Мало того, многоточие может не являться окончанием предложения, а быть, например, элементом усекания текста при цитировании.

вообще, комбинаций, мягко говоря, не мало

Так что надо искать знак препинания + 0-n пробелов  с последующей заглавной буковой или коротким тире (если мы говорим о прямой речи ).

Вообще, у нас язык очень тяжел для парсинга.
Особенность русского языка в том, что постановка подлежащего и сказуемого в нашем языке абсолютно не важна. Мы определяем смысл предложения через интонацию, которую в письме передаем через символы пунктуации.

SeVlad
На сайте с 03.11.2008
Offline
1609
#22
silicoid #:
Мало того, есть ещё комбинации вопроса с восклицанием. (?!)
Правила русского языка допускают также три восклицательных знака (!!!)

С этим проще - после них пробел.

silicoid #:
Мало того, многоточие может не являться окончанием предложения, а быть, например, элементом усекания текста при цитировании.

В этом случае дОлжно использовать две точки (..), а не троеточие. Но согласен, что не все такие нюансы знают-используют (как и напр некоторые забивают на большую букву в начале предложения :) ). И в любом случае с этим тоже есть заморочки для разбора.

silicoid #:
Особенность русского языка в том, что постановка подлежащего и сказуемого в нашем языке абсолютно не важна. Мы определяем смысл предложения через интонацию, которую в письме передаем через символы пунктуации.

Ну а это вообще не важно для задачи ТСа.

Делаю хорошие сайты хорошим людям. Предпочтение коммерческим направлениям. Связь со мной через http://wp.me/P3YHjQ-3.
D
На сайте с 01.01.2016
Offline
43
#23

немогу понять почему не работает если задать свое значение при вызове функции

function tease($body, $sentencesToDisplay = 2) {
        $nakedBody = preg_replace('/\s+/',' ',strip_tags($body));
        $sentences = preg_split('/(\.|\?|\!)(\s)/',$nakedBody);
    
        if (count($sentences) <= $sentencesToDisplay)
            return $nakedBody;
    
        $stopAt = 0;
        foreach ($sentences as $i => $sentence) {
            $stopAt += strlen($sentence);
    
            if ($i >= $sentencesToDisplay - 1)
                break;
        }
    
        $stopAt += ($sentencesToDisplay * 2);
        return trim(substr($nakedBody, 0, $stopAt));
    }

если вот так работает

echo tease($text);

а вот так нет

echo tease($text, 4);

пАтиму??

Пусто...
S
На сайте с 13.10.2014
Offline
171
#24

Интересно взглянуть в глаза программисту, который использует foreach там, где он вообще нафих не нужен. (Может он просто не знает, что есть и другие операторы цикла?)
тут надо for обычный юзать, Он и читается проще и , главное, в данном случае работает зело быстрее.

"пАтиму??"
а вот... Тут или регэексп находит всего два предложения или ...  одно из двух. (с) Колобки

T7
На сайте с 19.09.2018
Offline
63
#25
SeVlad #:

А если есть, то 4 раза (с каждым возможным разделителем ;))

Ида. Надо искать не точку, а точку с пробелом.

Но ещё вспомнилась засада - если в тексте есть сокращения, то всё намного хуже.

Так уж и 4 раза? 15 мин на коленке:

<?php
$a = 'А если есть, то 4 раза!!! С каждым возможным разделителем; Ида... Т..н. (так называемые) нюансы. Надо искать не точку, а точку с пробелом! Но ещё вспомнилась засада! Если в тексте есть т.н. сокращения, то всё намного хуже.
вопроса с восклицанием?! Правила русского языка допускают также три восклицательных знака!!!
а вот... Тут или регэексп находит всего два предложения или ...  одно из двух';
echo "\nOriginal: ", $a, "\n";
$a =  preg_split("//u", $a, -1, PREG_SPLIT_NO_EMPTY);
$l = count($a);
$passage_separator = ['.', '!', '?'];
$res = [];
$str = '';

for($i=0;$i<$l;$i++){
  if(in_array($a[$i], $passage_separator)) {
    $j = $i+1;
    while($j<$l){
      #смотрим на последующие символы, в зависимости от (. А) или (. а)
      if(!in_array($a[$j], $passage_separator)){
        #для упрощения, считаем, что разделитель всегда пробел.
        if(
          $a[$j]==' '
          &&  preg_match('~\p{Lu}~u', $a[$j+1])
        ) {
          #как только пробел и следующий символ уппер_кейс, собранную строку в массив и обнуляем
          if($str) $res[] = $str;
          $str = '';
        } else {
          $str.=$a[$j-1];
        }        
        break;
      }
      $j++;      
    }
  }
  else {
    $str.=$a[$i];
  }
}
if ($str) $res[] = $str; #если что то осталось
print_r($res);
#trim? Обработку, чтобы не попадали пустые строки, оставляю другим
?>

Результат:

php -f /var/web/php_temp/tt.php

Original: А если есть, то 4 раза!!! С каждым возможным разделителем; Ида... Т..н. (так называемые) нюансы. Надо искать не точку, а точку с пробелом! Но ещё вспомнилась засада! Если в тексте есть т.н. сокращения, то всё намного хуже.
вопроса с восклицанием?! Правила русского языка допускают также три восклицательных знака!!!
а вот... Тут или регэексп находит всего два предложения или ...  одно из двух
Array
(
    [0] => А если есть, то 4 раза
    [1] =>  С каждым возможным разделителем; Ида
    [2] =>  Т..н. (так называемые) нюансы
    [3] =>  Надо искать не точку, а точку с пробелом
    [4] =>  Но ещё вспомнилась засада
    [5] =>  Если в тексте есть т.н. сокращения, то всё намного хуже.
вопроса с восклицанием
    [6] =>  Правила русского языка допускают также три восклицательных знака!!!
а вот
    [7] =>  Тут или регэексп находит всего два предложения или ...  одно из двух
)
D
На сайте с 01.01.2016
Offline
43
#26
но в массив попадает голые слова, а как же знаки в конце предложения?
D
На сайте с 01.01.2016
Offline
43
#27

оффторп

форточники в шоке:

php -f /var/web/php_temp/tt.php
T7
На сайте с 19.09.2018
Offline
63
#28
Drinktea #:
а как же знаки в конце предложения?

покрутить назад, до первого символа !разделитель_пассажа, перед отгрузкой в массив, что то типа:

$s='';
while(true){
    $j--;
    if(in_array($a[$j], $passage_separator)){
      $s.=$a[$j];
    } else break;
}
$res[] = $str . $s;

Или собирать разделители_пассажей. Но, с оглядкой,  что в строке они могут быть не только в конце предложения. Например в сокращениях.

SeVlad
На сайте с 03.11.2008
Offline
1609
#29
timo-71 #:
Так уж и 4 раза?

Тогда речь шла о 4 возможных разделителях и реализации без регулярок и массивов. ;)

S
На сайте с 13.10.2014
Offline
171
#30
        public function index()
        {
                $text = file_get_contents(FCPATH.'peace_and_war.txt');
                print_r($this->text_explode($text,5));
        }
        
        
        public function text_explode($text, $length = 4, $offset=0)
        {
                // удаляем символы табуляции и переводы строк
                // размечаем документ для последующего деления
                $text = preg_replace(['/\R+|\t+/imu', '/\s+/imu', '/^\s+/imu', '/(\[)\s+|\s+(\])/imu', '/(\.+\s+)|(\!+\s+)|(\?+\s+)|(\?\!\s+)/imu', '/(\.+\]\s+)|(\!+\]\s+)|(\?+\]\s+)|(\?\!\]\s+)/imu' ],['', ' ', '', '$1', '$1{:separate:}', '$1{:separate:}'],$text);
                
                // делим
                $text_exploded = explode('{:separate:}',$text);
                return array_slice ($text_exploded,$offset, $length);  
        }
Ловите
Последний в списке регэксп костылирует любимоую "особенность" Льва Николаевича забирать пояснения в квадратные скобки. Его, в принципе, можно убрать.
1 234

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий