Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [RegEx]извлечение слов из строки, с (вложенными)кавычками 
V
    Опции темы
kasmanaft
Дата 19.11.2007, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Нет, чуть-чуть не так smile

Вот.
Код
    // Разбираем строку на слова
    $reg = '/"(?=\S)(?:[^"]*|(?R))*(?<=\S)"/is';
    preg_match_all($reg, $search, $words1, PREG_PATTERN_ORDER);

    $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is';
    preg_match_all($reg, $search, $words2, PREG_PATTERN_ORDER);
    
    $words[0] = array_merge($words1[0], $words2[0]);


И вот
Код
                default: // Наличие хотя бы одного слова
                    $word = trim($word, '\\"');
                    $words_groups['any'][] = $word;  


UPD ну что ты будешь делать, опять "вопрос" куда-то пропал  smile
Скопируйте заново (я обновил)

Это сообщение отредактировал(а) kasmanaft - 19.11.2007, 19:20
PM MAIL   Вверх
Splendid
Дата 19.11.2007, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



обновила, спасибо!!!
Только с кавычками в кавычках та же историяsmile

Добавлено через 11 минут
странно, еще почему-то у некоторых слов первая или последняя буква отрезается...:(
PM MAIL   Вверх
kasmanaft
Дата 19.11.2007, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Ну как же так же, я с ума сейчас сойду smile  smile  smile 

А что Вы ищете? Может быть, неправильно оформлена строка? Кавычки должны окружать слово (словосочетание), без пробелов. ("текст "текст" текст", а не "текст"текст"текст" или "текст " текст " текст ").
Код

function prepareWhere($search, $fields)
{
    if ($search!=''){
    // Разбираем строку на слова
    $reg = '/"(?=\S)(?:[^"]*|(?R))*(?<=\S)"/is';
    preg_match_all($reg, $search, $words1, PREG_PATTERN_ORDER);

    $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is';
    preg_match_all($reg, $search, $words2, PREG_PATTERN_ORDER);
    
    $words[0] = array_merge($words1[0], $words2[0]);
    
    $words_groups = array();
    $words_groups['include']=array();
    $words_groups['exclude']=array();
    $words_groups['any']=array();
    
    // Каждое слово обрабатываем, определяем его тип
    foreach( $words[0] as $word )
    {
        $word = trim($word); // Удаляем лишние пробелы
        if( strlen($word) > 0 ) // Если слово не пустое, то продалжаем с ним
        {
            $word = addslashes($word);
            $word = addCslashes($word, '_%');
            switch( $word[0] )
            {
                case '+': // Обязательные слова
                    $words_groups['include'][] = substr($word, 1);
                    break;
                case '-': // Ненужные слова
                    $words_groups['exclude'][] = substr($word, 1);
                    break;
                default: // Наличие хотя бы одного слова
                    $word = trim($word, '"\\');
                    $words_groups['any'][] = $word;  
            }
        }
    }
    
    // "Группируем" группы слов, учитывая поля 
    $words_rules = array();
    $words_rules['include']=array();
    $words_rules['exclude']=array();
    $words_rules['any']=array();
    
    foreach( $fields as $field )
    {
        // Ненужные слова
        if( count($words_groups['exclude']) > 0 )
        
        $words_rules['exclude'][] = ' ('.$field.' NOT LIKE "%'. implode('%" AND '.$field.' NOT LIKE "%', $words_groups['exclude']) .'%" OR '.$field.' is null) ';
        
        // Наличие хотя бы одного слова            
        if( count($words_groups['any']) > 0 )

            $words_rules['any'][] = ' ('.$field.' LIKE "%'. implode('%" OR '.$field.' LIKE "%', $words_groups['any']) .'%") ';
    }
    
        if( count($words_groups['include']) > 0 ) 
        foreach( $words_groups['include'] as $word )
 
            $words_rules['include'][] = ' ('.implode(' LIKE "%'.$word.'%" OR ', $fields).' LIKE "%'.$word.'%") ';
            
    
    // Объединяем результаты
    if( count($words_rules['include']) > 0 )
        $where['include'] = '('.implode(' AND ', $words_rules['include']).')';
    if( count($words_rules['exclude']) > 0 )
        $where['exclude'] = '('.implode(' AND ', $words_rules['exclude']).')'; 
    if( count($words_rules['any']) > 0 )
        $where['any'] = '('.implode(' OR ', $words_rules['any']).')';
   
 $where = implode(' AND ', $where);
    return $where;
    }
}
;


Добавлено через 6 минут и 51 секунду
Ага, похоже до меня наконец-таки дошло.

Попробуйте после первого preg_match_all() вставить
    $search = preg_replace($reg, "", $search);
То есть
Код

    // Разбираем строку на слова
    $reg = '/"(?=\S)(?:[^"]*|(?R))*(?<=\S)"/is';
    preg_match_all($reg, $search, $words1, PREG_PATTERN_ORDER);

    $search = preg_replace($reg, "", $search);

    $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is';
    preg_match_all($reg, $search, $words2, PREG_PATTERN_ORDER);

PM MAIL   Вверх
Splendid
Дата 20.11.2007, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



изменила, ввожу вот так: "Закон Республики Беларусь "О научно-технической информации""

не то ищет...
вот как разбивает:

LIKE "%Закон Республики Беларусь %" OR LIKE "%%" OR  LIKE "%О%" OR  LIKE "%научно-технической%" OR LIKE "%информации%")


до последних изменений разбивал так:
LIKE "%Закон Республики Беларусь %" OR LIKE "%%" OR  LIKE "%Закон%" OR LIKE "%Республики%" OR LIKE "%Беларусь%" OR LIKE "%О%" OR LIKE "%научно-технической%" OR LIKE "%информации%") 


PM MAIL   Вверх
kasmanaft
Дата 20.11.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Странно.. у меня вот как разбивает:
Если "кавычки в кавычках" : LIKE "%Закон Республики Беларусь \"О научно-технической информации%") )
И без кавычек: LIKE "%О научно-технической информации%" OR LIKE "%Закон%" OR LIKE "%Республики%" OR LIKE "%Беларусь%") )

 smile 

Прикреплю на всякий случай код:
Код

<?php
function prepareWhere($search, $fields)
{
    if ($search!=''){
    // Разбираем строку на слова
    $reg = '/"(?=\S)(?:[^"]*|(?R))*(?<=\S)"/is';
    preg_match_all($reg, $search, $words1, PREG_PATTERN_ORDER);

    $search = preg_replace($reg, "", $search);

    $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is';
    preg_match_all($reg, $search, $words2, PREG_PATTERN_ORDER);
    
    $words[0] = array_merge($words1[0], $words2[0]);
    
    $words_groups = array();
    $words_groups['include']=array();
    $words_groups['exclude']=array();
    $words_groups['any']=array();
    
    // Каждое слово обрабатываем, определяем его тип
    foreach( $words[0] as $word )
    {
        $word = trim($word); // Удаляем лишние пробелы
        if( strlen($word) > 0 ) // Если слово не пустое, то продалжаем с ним
        {
            $word = addslashes($word);
            $word = addCslashes($word, '_%');
            switch( $word[0] )
            {
                case '+': // Обязательные слова
                    $words_groups['include'][] = substr($word, 1);
                    break;
                case '-': // Ненужные слова
                    $words_groups['exclude'][] = substr($word, 1);
                    break;
                default: // Наличие хотя бы одного слова
                    $word = trim($word, '"\\');
                    $words_groups['any'][] = $word;  
            }
        }
    }
    
    // "Группируем" группы слов, учитывая поля 
    $words_rules = array();
    $words_rules['include']=array();
    $words_rules['exclude']=array();
    $words_rules['any']=array();
    
    foreach( $fields as $field )
    {
        // Ненужные слова
        if( count($words_groups['exclude']) > 0 )
        
        $words_rules['exclude'][] = ' ('.$field.' NOT LIKE "%'. implode('%" AND '.$field.' NOT LIKE "%', $words_groups['exclude']) .'%" OR '.$field.' is null) ';
        
        // Наличие хотя бы одного слова            
        if( count($words_groups['any']) > 0 )

            $words_rules['any'][] = ' ('.$field.' LIKE "%'. implode('%" OR '.$field.' LIKE "%', $words_groups['any']) .'%") ';
    }
    
        if( count($words_groups['include']) > 0 ) 
        foreach( $words_groups['include'] as $word )
 
            $words_rules['include'][] = ' ('.implode(' LIKE "%'.$word.'%" OR ', $fields).' LIKE "%'.$word.'%") ';
            
    
    // Объединяем результаты
    if( count($words_rules['include']) > 0 )
        $where['include'] = '('.implode(' AND ', $words_rules['include']).')';
    if( count($words_rules['exclude']) > 0 )
        $where['exclude'] = '('.implode(' AND ', $words_rules['exclude']).')'; 
    if( count($words_rules['any']) > 0 )
        $where['any'] = '('.implode(' OR ', $words_rules['any']).')';
   
 $where = implode(' AND ', $where);
    return $where;
    }
}
;

echo prepareWhere('Закон Республики Беларусь "О научно-технической информации"', array(''));
?>

PM MAIL   Вверх
Splendid
Дата 20.11.2007, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



я поняла, у меня подставляется вот так:

\"Закон Республики Беларусь \"О научно-технической информации\"\", ибо экранирование есть...

А можно без экранирования в запрос подставлять? Это безопасно?
PM MAIL   Вверх
kasmanaft
Дата 20.11.2007, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Нет, конечно, не безопасно.

Но ведь $word = trim($word, '"\\') должен отрезать эти экранированные кавычки.. Вы его заменили?

PS выложил код, забыл кой-чего исправить:
$word = addslashes($word); - вместо него у Вас должен быть 
$word = mysql_real_escape_string($word); 
(с mysql_real_escape_string не работало у меня, т.к. нет соединения с БД)

PSPS ну блин smile  У Вас, похоже, включены магические кавычки, а текст приходит из формы?
Вообще полученный текст сразу же нужно очищать от работы этих магических кавычек вот такой конструпцией:
Код

// получили значение
$search = $_POST['search'];
// если включены магические кавычки
if (get_magic_quotes_gpc())
    // "отменяем" экранирование
    $search = stripslashes($search);

А после этого с $search уже можно работать...

Это сообщение отредактировал(а) kasmanaft - 20.11.2007, 12:21
PM MAIL   Вверх
Splendid
Дата 20.11.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



у меня приходит значение из формы, и обрабатывается перед подстановкой в нашу функцию так:

Код

function strips(&$el) { 
  if (is_array($el)) 
    foreach($el as $k=>$v) 
      strips($el[$k]); 
  else $el = stripslashes($el); 

if (get_magic_quotes_gpc()) { 
  strips($_GET);
  strips($_POST);
  strips($_COOKIE); 
  strips($_REQUEST);
  if (isset($_SERVER['PHP_AUTH_USER'])) strips($_SERVER['PHP_AUTH_USER']); 
  if (isset($_SERVER['PHP_AUTH_PW']))   strips($_SERVER['PHP_AUTH_PW']);
}
include "config.php";
include "query.php";
//Введенное пользователем значение
$search = $_REQUEST['search'];
$search=str_replace('\\','\\\\',$search);
$search=mysql_real_escape_string($search);
//убираем знаки препинания
$search=eregi_replace ('[?!()#:;|.]', '', $search);
//Замена нескольких пробелов на один: 
$search=ereg_replace(" +"," ",$search);
//Удаление лишних пробелов по-левому и правому боку текста:
$search=trim($search);
//чтобы _ и % соответствовали точно самим себе
$search=addCslashes($search, '_%');


вот....это правильно? этого достаточно?

Добавлено через 6 минут и 34 секунды
кажется я поняла, мне надо перед функцией убрать 

$search=mysql_real_escape_string($search);


так как в функции уже есть

$word = mysql_real_escape_string($word);  и поэтому происходит двойное экранирование, так?smile
PM MAIL   Вверх
kasmanaft
Дата 20.11.2007, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Точно!  smile 


Однако вот это лишнее...
Код

//убираем знаки препинания
$search=eregi_replace ('[?!()#:;|.]', '', $search);
//Замена нескольких пробелов на один: 
$search=ereg_replace(" +"," ",$search);
//Удаление лишних пробелов по-левому и правому боку текста:
$search=trim($search);
//чтобы _ и % соответствовали точно самим себе
$search=addCslashes($search, '_%');


Это сообщение отредактировал(а) kasmanaft - 20.11.2007, 12:38
PM MAIL   Вверх
Splendid
Дата 20.11.2007, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



ОГРОМНЕЙШЕЕ спасибо!!!! smile  smile 
PM MAIL   Вверх
Splendid
Дата 20.11.2007, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



а почему лишнее?

PM MAIL   Вверх
kasmanaft
Дата 20.11.2007, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



1) знаки препинания - потому что на них функция не станет обращать внимания, т.е. они не помешают. А, если удалить, скажем, запятую, находящуюся в кавычках -  ничего не найдется.
2) Замена нескольких пробелов на один - аналогично знакам препинания...
3) Удаление лишних пробелов по-левому и правому боку текста - тоже незачем..
4) чтобы _ и % соответствовали точно самим себе - эта же функция применяется внутри prepareWhere.. Если два раза экранировать, получится, что экранируется "\", а _% останутся нетронутыми.

PS наконец-то мы её победили smile 
PM MAIL   Вверх
Splendid
Дата 20.11.2007, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



не, не мы, а Выsmile я так, прослушала лекциюsmile Спасибо!

Добавлено через 6 минут и 25 секунд
вот еще вылезло: 
если в поисковую строку просто ввести какой-нибудь из символов: . \ , " № ; @ # & ну и так далее, то 
Notice: Undefined variable: where in F:\Program Files\wamp\www\reestr_skript18\search.php on line 151

Добавлено через 12 минут и 4 секунды
что с этим делать?
PM MAIL   Вверх
kasmanaft
Дата 20.11.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 16.11.2007

Репутация: 1
Всего: 2



Так-так-таак..
Можно попробовать
Код
 if ($search!=''){
заменить на
Код
if (preg_match("/[а-яА-ЯёЁa-zA-Z0-9]/", $search)){

PS а что раньше было, если передать в функцию пустую строку? 
Если все нормально было, то должно сработать..
PM MAIL   Вверх
Splendid
Дата 20.11.2007, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 256
Регистрация: 1.8.2007
Где: Беларусь, Минск

Репутация: нет
Всего: нет



раньше с пустой строкой была проверка: 

Код

if ($search == '')
 {echo '</br>';
   echo " <center><br> Вы ничего не ввели в окно поиска.
    Пожалуйста, повторите ввод. </br></center>";
 }


Сейчас с пустой нормально, а вот с этими символами:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in F:\Program Files\wamp\www\reestr_skript18\search.php on line 173

т.е. $where нету, следовательно запрос неправильный....
значит теперь нужно ввести проверку типа 

if ($where == '')
 {echo '</br>';
   echo " <center><br> То чего-то там. </br></center>";
 }

????

Добавлено через 1 минуту и 37 секунд
т.е. теперь пользователь может вводить только русские и англ. буквы и цифры...так?

Добавлено через 2 минуты и 40 секунд
а почему? регулярные выражения не воспринимают  \ , " № ; @ # & и так далее??
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.1332 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.