Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Помогите составить PHP код поиска нужных слов в переменной.
 
 автор: sega_z   (30.04.2011 в 19:59)   письмо автору
 
 

Всем добрый день!

Никак не получается составить PHP код поиска нужных слов в переменной.

Допустим есть переменная:


$text="Однажды в студеную, зимнею пору я из лесу вышел - был сильный мороз. Гляжу поднимается медленно в гору лошадка, везущая хворосту воз.";


Необходимо найти своего рода стоп-слова, например:


$stop="медленно в гору";


Заранее благодарен!

  Ответить  
 
 автор: nikita2206   (30.04.2011 в 20:06)   письмо автору
 
   для: sega_z   (30.04.2011 в 19:59)
 

strpos(); ??

  Ответить  
 
 автор: sega_z   (30.04.2011 в 20:13)   письмо автору
 
   для: nikita2206   (30.04.2011 в 20:06)
 

Дак это поиск символа в слове, а у меня поиск слов в строке.


<?php
$mystring 
'abc';
$findme   'a';
$pos strpos($mystring$findme);

// Note our use of ===.  Simply == would not work as expected
// because the position of 'a' was the 0th (first) character.
if ($pos === false) {
    echo 
"The string '$findme' was not found in the string '$mystring'";
} else {
    echo 
"The string '$findme' was found in the string '$mystring'";
    echo 
" and exists at position $pos";
}
?>

  Ответить  
 
 автор: nikita2206   (30.04.2011 в 20:19)   письмо автору
 
   для: sega_z   (30.04.2011 в 20:13)
 

Да нет, можно и строку в строке искать.

  Ответить  
 
 автор: sega_z   (30.04.2011 в 20:28)   письмо автору
 
   для: nikita2206   (30.04.2011 в 20:19)
 

А если количество символов в строке - 3000?
Я видел примеры, где сначала текст переменной заносится в массив, а затем в массиве происходит поиск слов. Зачем тогда так делают, если есть проще варианты (о которых вы говорите)?

  Ответить  
 
 автор: cheops   (30.04.2011 в 20:21)   письмо автору
 
   для: sega_z   (30.04.2011 в 20:13)
 

Это в документации просто не удачный пример, strpos() и строки ищет, более того, вариант stripos() позволяет искать строки, без учета регистра.

  Ответить  
 
 автор: sega_z   (30.04.2011 в 20:24)   письмо автору
 
   для: cheops   (30.04.2011 в 20:21)
 

А этот оператор будет работать, если в тексте будут переносы строк и различные знаки препинания?

  Ответить  
 
 автор: cheops   (30.04.2011 в 20:41)   письмо автору
 
   для: sega_z   (30.04.2011 в 20:24)
 

Если вы их в точности воспроизведете, то да. Если в этом есть сомнения, лучше сразу обратиться к регулярным выражениям.

  Ответить  
 
 автор: sega_z   (30.04.2011 в 21:33)   письмо автору
 
   для: cheops   (30.04.2011 в 20:41)
 

Боюсь с регулярными выражениями не получится, т.к. текст может быть разнообразным до 3000 символов.
Мне просто нужно определить стоп-слова, которые не должны встречаться в тексте.

  Ответить  
 
 автор: cheops   (30.04.2011 в 21:36)   письмо автору
 
   для: sega_z   (30.04.2011 в 21:33)
 

>3000 символов
В искомом тексте или в тексте, в котром поиск производится.

>Мне просто нужно определить стоп-слова, которые не должны встречаться в тексте.
Вот тут не очень понятно, эти слова заранее определены или их нужно как-то сгенерировать?

  Ответить  
 
 автор: sega_z   (30.04.2011 в 21:43)   письмо автору
 
   для: cheops   (30.04.2011 в 21:36)
 

Объясню по подробнее:

Есть текстовое поле формы на сайте, в котором пользователи вводят некий текст до 3000 символов.
Мне необходимо задать определенные стоп-слова, при обнаружении которых скрипт не будет заносить вышеуказанный текст в базу данных.
Стоп-слова состоят из одного-трех слов.

Вот примерно так.

  Ответить  
 
 автор: cheops   (30.04.2011 в 22:27)   письмо автору
 
   для: sega_z   (30.04.2011 в 21:43)
 

Хм... собственно и strpos() и регулярные выражения прекрасно должны справиться с этой задачей.
<?php 
  
function check($text)
  {
    
$arr = array("sex""porno");
    for(
$i 0$i count($arr); $i++)
    {
      if(
stripos($text$arr[$i]) !== false)
      {
        return 
false;
      }
    }
    return 
true;
  }
?>

  Ответить  
 
 автор: sega_z   (30.04.2011 в 22:46)   письмо автору
 
   для: cheops   (30.04.2011 в 22:27)
 

Спасибо!!!
А как подключить приведенную вами функцию к полю формы:


<textarea name="text_obyavl" cols="70" rows="5" required class="pole" id="text_obyavl"><?php echo @$_POST['text_obyavl'?></textarea>

  Ответить  
 
 автор: cheops   (30.04.2011 в 22:59)   письмо автору
 
   для: sega_z   (30.04.2011 в 22:46)
 

Это от обработчика зависит и от способа вывода информации об ошибках или неправильном вводе. Обычно поступают как-то так
<?php
  
...
  
$error = array();
  if(!
check($_POST['text_obyavl'])) $error[] = "Сообщение содержит недопустимые слова и символы";
  ...
?>
А далее контролируют состояние массива $error - если он пустой: добавляют сообщение в базу данных, если что-то содержит: выводят форму и сообщения в массиве $error, чтобы посетитель имел возможность поправить сообщение.

  Ответить  
 
 автор: sega_z   (30.04.2011 в 23:13)   письмо автору
 
   для: cheops   (30.04.2011 в 22:59)
 

А в моём случае в вашей функции не нужно менять $text на $_POST['text_obyavl'] ?

  Ответить  
 
 автор: cheops   (30.04.2011 в 23:23)   письмо автору
 
   для: sega_z   (30.04.2011 в 23:13)
 

Вы осуществляете эту замену при вызове функции (как двумя постами выше), внутри функции менять не нужно.

  Ответить  
 
 автор: sega_z   (01.05.2011 в 00:23)   письмо автору
 
   для: cheops   (30.04.2011 в 23:23)
 

Хорошо вроде теперь понятно, будем пробовать. Спасибо огромное!!!

  Ответить  
 
 автор: sega_z   (01.05.2011 в 00:44)   письмо автору
 
   для: cheops   (30.04.2011 в 23:23)
 

Что то у меня не получается, наверно потому, что к текстовому полю формы прицеплен скрипт проверки наличия текста.
А вы не могли бы написать данный код без использования функции?

  Ответить  
 
 автор: cheops   (01.05.2011 в 10:33)   письмо автору
 
   для: sega_z   (01.05.2011 в 00:44)
 

Собственно он практически не изменяется, только вместо $text, нужно подставить ваше значение
<?php
    $arr 
= array("sex""porno"); 
    for(
$i 0$i count($arr); $i++) 
    { 
      if(
stripos($_POST['text_obyavl'], $arr[$i]) !== false
      { 
        
$error[] = "Сообщение содержит недопустимые слова и символы"
        
break;
      } 
    } 
?>

  Ответить  
 
 автор: sega_z   (01.05.2011 в 11:19)   письмо автору
 
   для: cheops   (01.05.2011 в 10:33)
 

Хорошо, большое спасибо вам, сейчас попробую ...

  Ответить  
 
 автор: sega_z   (01.05.2011 в 11:31)   письмо автору
 
   для: cheops   (01.05.2011 в 10:33)
 

Да теперь всё работает, спасибо вам ОГРОМНОЕ!!!
Хорошо, когда на форуме данного типа встречаются действительно хорошие специалисты.

Хотелось бы уточнить один нюанс: для остановки кода в вашем случае вы использовали функцию "break", а я использую "exit". Что лучше использовать?

  Ответить  
 
 автор: cheops   (01.05.2011 в 11:45)   письмо автору
 
   для: sega_z   (01.05.2011 в 11:31)
 

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

[поправлено модератором: ветка про IP-адреса выделена в новую тему]

  Ответить  
 
 автор: sega_z   (01.05.2011 в 12:45)   письмо автору
 
   для: cheops   (01.05.2011 в 11:45)
 

Можно ли как нибудь сделать, чтобы в данном коде учитывались заглавные буквы:


<?php
    $arr 
= array("sex""porno"); 
    for(
$i 0$i count($arr); $i++) 
    { 
      if(
stripos($_POST['text_obyavl'], $arr[$i]) !== false
      { 
        
$error[] = "Сообщение содержит недопустимые слова и символы"
        
break;
      } 
    } 
?> 

  Ответить  
 
 автор: cheops   (01.05.2011 в 12:47)   письмо автору
 
   для: sega_z   (01.05.2011 в 12:45)
 

Если я правильно понял что требуется, достаточно набрать стоп-слова заглавными буквами, а stripos() заменить на strpos()
<?php 
    $arr 
= array("SEX""PORNO");  
    for(
$i 0$i count($arr); $i++)  
    {  
      if(
strpos($_POST['text_obyavl'], $arr[$i]) !== false)  
      {  
        
$error[] = "Сообщение содержит недопустимые слова и символы" 
        
break; 
      }  
    }  
?>

  Ответить  
 
 автор: sega_z   (01.05.2011 в 13:01)   письмо автору
 
   для: cheops   (01.05.2011 в 12:47)
 

И в этом случае будут учитываться все способы написания слов? (Sex, SEX и т.д.)

  Ответить  
 
 автор: cheops   (01.05.2011 в 13:14)   письмо автору
 
   для: sega_z   (01.05.2011 в 13:01)
 

А нет, наоборот... чтобы регистр не учитывался, используйте первоначальный вариант с stripos(), в этом случае будут учитываться все способы написания.

  Ответить  
 
 автор: sega_z   (01.05.2011 в 13:18)   письмо автору
 
   для: cheops   (01.05.2011 в 13:14)
 

Но дело в том, что когда я написал слово "Легальные смеси" в сообщении (при этом в стоп-словах было указано - "легальные смеси"), то скрипт не сработал. Или это из-за того, что я указал слово в начале сообщения?

  Ответить  
 
 автор: cheops   (01.05.2011 в 13:24)   письмо автору
 
   для: sega_z   (01.05.2011 в 13:18)
 

Вы где тестируете скрипт: на локальной машине или на сервере (на сервере могут быть еще проблемы с локалью, т.е. PHP может не понимать что перед ним строка по русски, а не бинарная последовательность)? Вот этот скрипт у вас что выводит?
<?php  
  $_POST
['text_obyavl'] = "Порошки";
  
$arr = array("порошки""PORNO");   
  for(
$i 0$i count($arr); $i++)   
  {   
    if(
stripos($_POST['text_obyavl'], $arr[$i]) !== false)   
    {   
      exit(
"Сообщение содержит недопустимые слова и символы");
    }   
  }   
  echo 
"Все хорошо";
?>

  Ответить  
 
 автор: sega_z   (01.05.2011 в 13:33)   письмо автору
 
   для: cheops   (01.05.2011 в 13:24)
 

Я тестировал сразу на сервере, скрипт работал. Но если я заменял первую букву в поле текста на заглавную, то код пропускал это слово.

Последний скрипт я протестировал на локальном сервере, он выдал: "Сообщение содержит недопустимые слова и символы". А на удаленном сервере выдал "Все хорошо!"

КАК БЫТЬ?

  Ответить  
 
 автор: cheops   (01.05.2011 в 14:05)   письмо автору
 
   для: sega_z   (01.05.2011 в 13:33)
 

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

  Ответить  
 
 автор: sega_z   (01.05.2011 в 14:09)   письмо автору
 
   для: cheops   (01.05.2011 в 14:05)
 

А если просто написать стоп-слова нескольких видов: Порошки, порошки, ПОРОШКИ?

  Ответить  
 
 автор: cheops   (01.05.2011 в 14:44)   письмо автору
 
   для: sega_z   (01.05.2011 в 14:09)
 

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

  Ответить  
 
 автор: sega_z   (01.05.2011 в 14:38)   письмо автору
 
   для: cheops   (01.05.2011 в 14:05)
 

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

  Ответить  
 
 автор: sega_z   (01.05.2011 в 14:44)   письмо автору
 
   для: cheops   (01.05.2011 в 14:05)
 

Техподдержка хостинга сообщила:

"Работа функций со строками зависит от кодировки самих данных, над которыми выполняются операции, а также от установленной на сервере локали. В большинстве случаев, проблема заключается именно в различии этих параметров.

То есть, если функция stripos работает с данными в кодировке cp1251, то и локаль, соответственно, перед этим должна быть изменена на ru_RU.cp1251."

Если честно, я ничего не понял!. Вы можете объяснить, что нужно сделать?

  Ответить  
 
 автор: cheops   (01.05.2011 в 14:46)   письмо автору
 
   для: sega_z   (01.05.2011 в 14:44)
 

Вот такую функцию в начале скрита выполните
<?php
  setlocale 
(LC_ALL, array ('ru_RU.cp1251''rus_RUS.1251'));
?>

  Ответить  
 
 автор: sega_z   (01.05.2011 в 14:54)   письмо автору
 
   для: cheops   (01.05.2011 в 14:46)
 

Всё, теперь работает нормально! Большое человеческое спасибо вам!!!!

А данный скрипт вместе с последней добавленной строкой будет сильно загружать сервер (при наличии около 50 стоп-слов)?

  Ответить  
 
 автор: cheops   (01.05.2011 в 14:59)   письмо автору
 
   для: sega_z   (01.05.2011 в 14:54)
 

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

  Ответить  
 
 автор: sega_z   (01.05.2011 в 15:03)   письмо автору
 
   для: cheops   (01.05.2011 в 14:59)
 

Просто у меня на данной странице еще и загружаются, обрезаются и форматируются изображения пользователей.

  Ответить  
 
 автор: cheops   (01.05.2011 в 15:07)   письмо автору
 
   для: sega_z   (01.05.2011 в 15:03)
 

Ну ничего страшного, пользователи достаточно терпеливо относятся к задержкам при добавлении сообщения и менее терпеливы при их отображении. Хотя я не думаю, что эта проверка сильно затормозит систему - тут достаточно быстрые операции.

  Ответить  
 
 автор: sega_z   (01.05.2011 в 15:18)   письмо автору
 
   для: cheops   (01.05.2011 в 15:07)
 

Я горжусь вашими знаниями Игорь Вячеславович!!!
Спасибо ещё раз!

Помогите, пожалуйста ещё с одним вопросом: тема "Почему скрипт списка SELECT работает не во всех браузерах?"
Тема закрыта.

  Ответить  
 
 автор: sega_z   (01.05.2011 в 16:27)   письмо автору
 
   для: cheops   (01.05.2011 в 15:07)
 

Техподдержка сообщила, что добавлением, указанной вами строки, не обойтись "Нет, конкретно для этого случая (stripos) вам необходимо использовать версию функции mb_stripos, которая предназначена для работы с мультибайтовыми кодировками."

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования