Подсчет вхождений частицы "не"

Тема в разделе "Регулярные выражения", создана пользователем Festem, 11 май 2015.

Модераторы: xpert13
  1. Festem

    Festem Постоялец

    Регистр.:
    4 сен 2014
    Сообщения:
    97
    Симпатии:
    26
    Задача - найти число слов "не" в переменной $post. Юзал конструкцию

    PHP:
    $numne1=substr_count($post' не ');
      
    $numne2=substr_count($post' НЕ ');
      
    $numne3=substr_count($post' Не ');
      
    $numne=$numne1+$numne2+$numne3;
    Но это, честно говоря, ужаснейший костыль, кроме того, он ошибочно считает вхождением такие слова как "неё", и не учитывает варианты с началом строки, или когда предложение оканчивается типа "не." . В одщем, ка кне крути, а без preg_match_all не обойтись, но маска
    PHP:
    ^[a-zA-Z0-9]+(не|НЕ|Не)+^[a-zA-Z0-9]
    не работает. Кто-то может помочь с рабочим примером?
     
  2. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.517
    Симпатии:
    1.365
    PHP:
    var_dump(preg_match_all("~(\sне\s)~iu"$txt));
    Модификатор i для учёта верхнего и нижнего регистра, т.е. помимо форм "не|НЕ|Не" захватит так же "нЕ"
     
    Последнее редактирование: 11 май 2015
    Festem нравится это.
  3. Festem

    Festem Постоялец

    Регистр.:
    4 сен 2014
    Сообщения:
    97
    Симпатии:
    26
    Не работает :(.

    PHP:

    $txt
    ="Но не в этом дело. Не удержать такого запала, правда не?";

    var_dump(preg_match_all("~(\sне\s)~iu"$txt));

    результат - bool(false), хотя в тексте 3 совпадения
     
  4. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.517
    Симпатии:
    1.365
    Добавил учёт начала строки + для захвата последнего "не", после которого может быть не только пробельный символ:
    PHP:
    var_dump(preg_match_all("~((^|\s)не[\s|\W]*)~Uiu"$txt$out));
    bool(false) может быть из-за кодировки текста, попробуйте в регулярке убрать модификатор "u" - именно маленький символ.

    Потому как с самой регуляркой проблем нет для актуальных версий php:
    Перейти по ссылке
     
    Последнее редактирование: 11 май 2015
    Festem нравится это.
  5. Festem

    Festem Постоялец

    Регистр.:
    4 сен 2014
    Сообщения:
    97
    Симпатии:
    26
    Да, спасибо большое, все работает
    ------------------------------------------------------
    К сожалению работает не корректно. Перейти по ссылке Слова типа "нет" тоже считает за "не", хотя судя по правилу - не должно было бы, ведь /W это небуквенный символ
    ------------------------------------------------------
    Разобрался. Может кому-то еще пригодиться, то условие
    PHP:
    var_dump(preg_match_all("~((^|\s|\W|\D)не(\W|\D))~Uiu"$txt$out));
    Перейти по ссылке

    Берет все слова не, что начинаются с начала строки, не цифры и не буквы (т.е. это уже не часть слова) и оканчиваются всем чем угодно, но ен цифрой и не буквой. Если есть замечания по регулярке - буду рад выслушать

    latteo
    , спасибо за то что навели на нужный путь
    ------------------------------------------------------
    И все-таки неправильно мой вариант работает - при строке
    PHP:
    $txt="Неё, в этом дело. Но удержать такого запала, правда?";
    Находит 1 вариант, хотя не должно было бы :( Перейти по ссылке

    Кто любит задачки "со звездочкой?", помогите советом, где ошибка
     
    Последнее редактирование модератором: 12 май 2015
  6. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    205
    Симпатии:
    258
    Festem нравится это.
  7. Festem

    Festem Постоялец

    Регистр.:
    4 сен 2014
    Сообщения:
    97
    Симпатии:
    26
    Не работает

    PHP:
    $txt="Да неё, в этом дело. Но удержать такого запала, правда?";


    var_dump(preg_match_all("~(?<![\p{L}\p{Nd}])(не)(?![\p{L}\p{Nd}])~i"$txt$out));
    var_dump(     $out   );
    выдает 1 вхождение, хотя его быть не должно, Причем, если вместо "неё" сделать "нет", то все работает. в чем причина?
     
    Последнее редактирование: 12 май 2015
  8. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    205
    Симпатии:
    258
    Так вроде речь была про юникод и в регулярке применялся модификатор /u.
    Вобще страницы того сервиса теста скриптов в кодировке utf-8 соответственно и все данные передаются тоже в utf-8. Если у вас скрипт в другой кодировке cp1251,koi8r,cp866
    то можно обойтись \w, но перед этим нужно установить правильную локаль вызовом setlocale

    PHP:
    setlocale(LC_ALL'ru_RU.cp1251');

    $txt="Да неё, в этом дело. Но удержать такого запала, правда?";

    var_dump(preg_match_all("~\bне\b~i"$txt$out));
    var_dump(  $out  );
     
    Последнее редактирование: 12 май 2015
    latteo и Festem нравится это.
  9. Festem

    Festem Постоялец

    Регистр.:
    4 сен 2014
    Сообщения:
    97
    Симпатии:
    26
    Да, действительно Перейти по ссылке с u работает, но как быть если страница в ср1251, и и с модификатором /u выдает bool(false). Переводить все на utf? Не хотелось, но видимо именно в кодировке эта проблема

    как именно обойтись /w?

    ---------------------------------------------------------------

    Этот вариант вообще не работает. Я остановился на варианте

    PHP:
    $txt="Да нет, не в этом дело. Гнет - вот что у неё причина всех ненастий.";

    var_dump(preg_match_all("~(?<![\p{L}\p{Nd}])не(?![\p{L}\p{Nd}])~i"$txt$out));
    var_dump(  $out  );
    Единственное что перед обработкой текста, все "ё" меняю на "е", и все работает. большое спасибо за помощь, задача решена
     
    Последнее редактирование: 12 май 2015