| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > PHP: Тексты > [RegEx]извлечение слов из строки |
| Автор: Splendid 19.11.2007, 11:49 | ||
| Подскажите, пожалуйста, как изменить это регулярное выражение? сейчас оно разбивает строку на слова: 1. перед которыми стоит минус 2. перед которыми стоит плюс 3. те, что заключены в кавычки "слово слово2" и фразу "Закон Республики Беларусь "О печати"" оно сейчас разбивает на: 1. Закон Республики Беларусь 2. о 3. печати Ну а надо, чтобы разбивало так: 1. Закон Республики Беларусь "О печати". Вот...помогите, пожалуйста...
|
| Автор: kasmanaft 19.11.2007, 12:38 |
| Здесь можно зацепиться за "" - две рядомстоящие кавычки. Попробуйте так: $pattern = '/(?(?=\")\".*\"(?![^\"]*\"\")|(\+|-)?(\b\w+\b))/iUs'; PS из-за этого, может быть, глючить будет в каких-нибудь хитрых местах. |
| Автор: Splendid 19.11.2007, 14:32 |
| kasmanaft, спасибо! Но это ведь частный случай - две рядом стоящие кавычки... здесь скорее как-то надо типа с первой кавычки по последнюю кавычку...просто я в регулярках не сильна, поэтому и спрашиваю |
| Автор: kasmanaft 19.11.2007, 15:38 |
| " издали " закон " о печати " блаблабла " " - вот попробуйте определить, что я здесь взял в кавычки По идее хотел вот так: "издали "закон "о печати" блаблабла"" . . . . |
| Автор: Splendid 19.11.2007, 15:44 |
| kasmanaft, у меня с этой регуляркой еще одна проблема возникла, при переносе на сервер она странно разбивает слова, например экран ищет как 2 слова: "к" и "ан", в чем здесь может быть проблема??? в некоторых словах обрезает последнюю букву, а некоторые нормально ищет... |
| Автор: kasmanaft 19.11.2007, 15:53 |
| Я сейчас подумаю как записать то, что напридумывал.. А ты покажи пока код свой. А то в зависимости от того какой функцией разбиваешь, разные проблемы могут быть.. И скорее всего предыдущую рег. экспу придется разбить на две... Потому что получится слишком заумно (а она и так, надо сказать, непростая) |
| Автор: Splendid 19.11.2007, 15:59 | ||
вот код:
Добавлено через 30 секунд причем локально все работает правильно |
| Автор: kasmanaft 19.11.2007, 16:13 | ||
| Ну начнем... Придумал вот что: /"(?=\S)(?:[^"]*|(?R))*(?<=\S)"/is Второе выражение, наверное, нужно вот таким оставить: (\+|-)(\b\w+\b) - убрал "+" после первой скобки, по-моему, он там не нужен. (объединить два выражения уже не получится, в первом использована рекурсия). Итого тебе осталось два раза использовать preg_match_all() и после этого объединить полученные массивы (третий аргумент). Проблемы на сервере могут быть из-за неправильно настроенной локали. Посмотри setlocale(). Может быть получится вот так setlocale (LC_ALL, array ('ru_RU.CP1251', 'rus_RUS.1251')), а может быть придется имена локалей уточнить у хостера.
Упс, а я и не приметил В таком случае, если чего не получится, помогу довести всё это дело до конца |
| Автор: Splendid 19.11.2007, 16:38 |
| Настройки локали у меня такие прописаны...но все равно глюки... я уже вообще ничего не соображаю.... Помогите Ваши регулярки в мой код подставить, пожалуйста.. |
| Автор: Splendid 19.11.2007, 17:43 |
| Спасибо! Пойду пробовать! а если такая локаль, то что прописывать надо: LANG = "ru_RU.UTF-8"???? |
| Автор: kasmanaft 19.11.2007, 18:05 |
| Просто заменить те, что были наверху на эту. Но, честно говоря, не знаю, изменит ли это что-нибудь или нет - текст-то ведь в CP1215, а тут UTF-8. Понял для чего нужен был тот вопросительный знак.. Всё-таки он был нужен. То есть вот так попровте: $reg = '/(?:\+|-)?\b\w+\b/is'; И насчет локали.. Вы говорите, неправильно ищет слово "экран". А если его в кавычки взять? Если так сработает, то можно второе рег. выражение попробовать оформить вот так: $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is'; |
| Автор: Splendid 19.11.2007, 18:12 | ||
| в кавычках работает... что же с этой локалью ничего сделать нельзя??? Может можно на серваке установить CP1215? Как вообще в этих случаях поступают? если подставлять ваши 2 выражения - то выдает кучу ошибок...сейчас приведу их Добавлено через 2 минуты и 12 секунд Notice: Undefined variable: where in F:\Program Files\wamp\www\reestr_skript18\search.php on line 153 это отсюда
надо видимо что-то еще в коде исравить |
| Автор: kasmanaft 19.11.2007, 18:58 | ||||
| Хм... странно. Я забыл, что кавычки там будут экранированные, поэтому надо: trim($word, '\\"'). (кстати, Вы $val заменили на $word? я просто так, в качестве примера этот код привел..) . . . . . . Ага.. понял в чем дело (про trim() не забудте). Вы, видимо, не обратили внимание на вот это:
Заменить лучше вот таким: $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is'; (это второе выражение) И попробуйте этот злополучный "экран" поискать (без кавычек).
|
| Автор: Splendid 19.11.2007, 19:10 | ||
в итоге должно получится вот так?
Вроде все ищет, спасибо огромное!!! Добавлено через 1 минуту правда кавычки в кавычках все равно не воспринимает |
| Автор: kasmanaft 19.11.2007, 19:16 | ||||
| Нет, чуть-чуть не так Вот.
И вот
UPD ну что ты будешь делать, опять "вопрос" куда-то пропал Скопируйте заново (я обновил) |
| Автор: Splendid 19.11.2007, 19:27 |
| обновила, спасибо!!! Только с кавычками в кавычках та же история Добавлено через 11 минут странно, еще почему-то у некоторых слов первая или последняя буква отрезается...:( |
| Автор: kasmanaft 19.11.2007, 19:54 | ||||
| Ну как же так же, я с ума сейчас сойду А что Вы ищете? Может быть, неправильно оформлена строка? Кавычки должны окружать слово (словосочетание), без пробелов. ("текст "текст" текст", а не "текст"текст"текст" или "текст " текст " текст ").
Добавлено через 6 минут и 51 секунду Ага, похоже до меня наконец-таки дошло. Попробуйте после первого preg_match_all() вставить $search = preg_replace($reg, "", $search); То есть
|
| Автор: Splendid 20.11.2007, 10:35 |
| изменила, ввожу вот так: "Закон Республики Беларусь "О научно-технической информации"" не то ищет... вот как разбивает: LIKE "%Закон Республики Беларусь %" OR LIKE "%%" OR LIKE "%О%" OR LIKE "%научно-технической%" OR LIKE "%информации%") до последних изменений разбивал так: LIKE "%Закон Республики Беларусь %" OR LIKE "%%" OR LIKE "%Закон%" OR LIKE "%Республики%" OR LIKE "%Беларусь%" OR LIKE "%О%" OR LIKE "%научно-технической%" OR LIKE "%информации%") |
| Автор: kasmanaft 20.11.2007, 11:22 | ||
| Странно.. у меня вот как разбивает: Если "кавычки в кавычках" : LIKE "%Закон Республики Беларусь \"О научно-технической информации%") ) И без кавычек: LIKE "%О научно-технической информации%" OR LIKE "%Закон%" OR LIKE "%Республики%" OR LIKE "%Беларусь%") ) Прикреплю на всякий случай код:
|
| Автор: Splendid 20.11.2007, 11:36 |
| я поняла, у меня подставляется вот так: \"Закон Республики Беларусь \"О научно-технической информации\"\", ибо экранирование есть... А можно без экранирования в запрос подставлять? Это безопасно? |
| Автор: kasmanaft 20.11.2007, 12:12 | ||
| Нет, конечно, не безопасно. Но ведь $word = trim($word, '"\\') должен отрезать эти экранированные кавычки.. Вы его заменили? PS выложил код, забыл кой-чего исправить: $word = addslashes($word); - вместо него у Вас должен быть $word = mysql_real_escape_string($word); (с mysql_real_escape_string не работало у меня, т.к. нет соединения с БД) PSPS ну блин Вообще полученный текст сразу же нужно очищать от работы этих магических кавычек вот такой конструпцией:
А после этого с $search уже можно работать... |
| Автор: Splendid 20.11.2007, 12:22 | ||
у меня приходит значение из формы, и обрабатывается перед подстановкой в нашу функцию так:
вот....это правильно? этого достаточно? Добавлено через 6 минут и 34 секунды кажется я поняла, мне надо перед функцией убрать $search=mysql_real_escape_string($search); так как в функции уже есть $word = mysql_real_escape_string($word); и поэтому происходит двойное экранирование, так? |
| Автор: kasmanaft 20.11.2007, 12:35 | ||
| Точно! Однако вот это лишнее...
|
| Автор: Splendid 20.11.2007, 12:39 |
| ОГРОМНЕЙШЕЕ спасибо!!!! |
| Автор: Splendid 20.11.2007, 12:55 |
| а почему лишнее? |
| Автор: kasmanaft 20.11.2007, 13:07 |
| 1) знаки препинания - потому что на них функция не станет обращать внимания, т.е. они не помешают. А, если удалить, скажем, запятую, находящуюся в кавычках - ничего не найдется. 2) Замена нескольких пробелов на один - аналогично знакам препинания... 3) Удаление лишних пробелов по-левому и правому боку текста - тоже незачем.. 4) чтобы _ и % соответствовали точно самим себе - эта же функция применяется внутри prepareWhere.. Если два раза экранировать, получится, что экранируется "\", а _% останутся нетронутыми. PS наконец-то мы её победили |
| Автор: Splendid 20.11.2007, 13:12 |
| не, не мы, а Вы Добавлено через 6 минут и 25 секунд вот еще вылезло: если в поисковую строку просто ввести какой-нибудь из символов: . \ , " № ; @ # & ну и так далее, то Notice: Undefined variable: where in F:\Program Files\wamp\www\reestr_skript18\search.php on line 151 Добавлено через 12 минут и 4 секунды что с этим делать? |
| Автор: kasmanaft 20.11.2007, 13:50 | ||||
| Так-так-таак.. Можно попробовать
PS а что раньше было, если передать в функцию пустую строку? Если все нормально было, то должно сработать.. |
| Автор: Splendid 20.11.2007, 14:06 | ||
раньше с пустой строкой была проверка:
Сейчас с пустой нормально, а вот с этими символами: 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 секунд а почему? регулярные выражения не воспринимают \ , " № ; @ # & и так далее?? |
| Автор: kasmanaft 20.11.2007, 14:35 | ||||||
Ну, он может вводить что захочет, но искаться будут только перечисленные Раньше, вроде бы, так же было.. Разве нет? И "Notice: Undefined variable" по идее должна была выскакивать при аналогичном вводе. Сейчас он ищет то, что находится в кавычках и то, что перечисленно во втором выражении $reg = '/(?:\+|-)?\b[a-zA-Zа-яёА-ЯЁ0-9-_]+\b/is'; Это выражение можно на словах расписать так: возможно стоит плюс или минус, после которого идут перечисленные в кв. скобках буквы/числа. Если нужно искать всё, что введет пользователь, можно квадратные скобки заменить на "\S". Если хотите ограничить длинну слова (чтобы исключить из поиска слишком короткие слова), можно после квадратных скобок (или \S - что выберете) убрать "+" и поставить "{3,}" - будет искать слова только от трех "букв" и больше. Вместо это проверки
Итак. Исходя из вышесказанного, налепил вот что:
PS опять забыл про mysql_real_escape_string(). Обновил |
| Автор: Splendid 20.11.2007, 15:13 |
| вроде как понятно... Спасибо огромное еще раз! |