webew
Войти » Регистрация
 
PHP

Регулярные выражения

14 июля 2008, 23:31
Автор: Serg_pnz
Никак не соображу как убрать \n

$com_text = str_replace("\n", "666", $com_text);

666 добавляет, но и перевод строки оставляет.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

rgbeast

Если виндовая кодировка, то перевод строки - два символа \r\n (исторически - carriage return и new line, ascii - 0xD, 0xA). Попробуйте так:

$com_text = preg_replace("/\r?\n/", "666", $com_text);
14.07.2008, 23:39
Ответить

Serg_pnz

Спасибо. Забыл решетки по бокам регулярки поставить...
$_POST['first_name'] = preg_replace("#\n#", "<br />", $_POST['first_name']);


А сутра вон чего намутил (не кидаться помидорами))) )
$_POST['first_name'] =  nl2br($_POST['first_name']);
$tmpm = explode("<br />", $_POST['first_name']);
$_POST['first_name'] = "";
foreach($tmpm as $key => $val) {
    if (trim($val)!="") $_POST['first_name'] .= trim($val)."<br />";
}
15.07.2008, 11:38
Ответить

Serg_pnz

БР-ки в предыдущем комменте съело.

Ну и уж не делать что бы новую ветку. Такая задача: есть куча подряд повторяющихся символов. Возьмем 8 для наглядности.
Как заменить строку 8888888888(8... не знаю сколько может быть) на 8 в один проход?
15.07.2008, 11:40
Ответить

Serg_pnz

Разобрался. Может кому пригодится
$_POST['first_name'] = preg_replace("#(8)+#s", "8", $_POST['first_name']);
15.07.2008, 12:09
Ответить

1234ru

Вот, придумал Вам такую штуку:

$_POST['first_name'] = preg_replace('#(.)\1+#s', '$1', $_POST['first_name']);


Способна совершить требуемую Вам операцию для любого символа (если, конечно, такое нужно).

\1 - это т.н. ссылка на подмаску. Запись \1+ означает "повторение один или более раз того, что было захвачено в первую подмаску". То есть если Вам нужно не один какой-то повторяющийся символ заменить, а некую последовательность, Вы просто составляете для нее выражение и помещаете в первую подмаску.

Передача preg_replace() в качестве второго аргумента строки '$1' означает "заменить найденную подстроку на содеримое первой подмаски".

Модификатор 's' при реализации через нужен, только если среди ваших повторяющихся символов будут переводы строки, и Вы будете их ловить в шаблоне через точку (.):
http://ru2.php.net/manual/ru/reference.pcre.pattern.modifiers.php

Если Вы используете фиксированный символ, необязательно заключать его в подмаску (так называется часть шаблона внутри круглых скобок). Можно просто '#8+#s'. - так компьютеру будет немного легче
То, что не убивает нас, делает нас инвалидами.
16.07.2008, 00:35
Ответить

Serg_pnz

Большое спасибо! Про одиночные понятно, а вот это
$_POST['first_name'] = preg_replace("#(sert)\1+#si", "$1", $_POST['first_name']);

всё равно возвращает
sertsertsertsert
16.07.2008, 12:18
Ответить

Serg_pnz

Осенило! Глюк редактора: перед единицей должно быть 2 слеша. Всё работает. Спасибо!
16.07.2008, 14:54
Ответить

1234ru

Пардон. br-ки ваши вернули :)
То, что не убивает нас, делает нас инвалидами.
16.07.2008, 00:32
Ответить

Serg_pnz

Вернули не только мои бр в выражении, но и бр в конце строки. Причем я смотрю по всему сайту. Нужен правильный баланс nl2br для бб-редактора (в своё время умучился для форума его, баланс, искать)
16.07.2008, 12:20
Ответить

1234ru

Ну, баланс тут, я думаю, простой: вне тегов [syntax] htmlspecialchars и nl2br, внутри - bbcode (просто вчера этот баланс нечаянно сломали - теперь br-ки там, где надо, есть, там где не надо - нет :) я так смотрю, вроде бы, все нормально щас)
То, что не убивает нас, делает нас инвалидами.
16.07.2008, 15:58
Ответить

Serg_pnz

А двойные слеши?
Тест:
$i = "\\1"


Тут работает. Не иначе в посте выше просто был один пропущен.
17.07.2008, 10:05
Ответить

1234ru

Нет, со слэшами всё нормально, действительно должен быть один.

Дело в том, что слэш является экранирующим символом не только в синтаксисе PCRE, но и в самом PHP при декларации строк. То есть, например, для захвата самого слэша при составлении регулярного выражения нужно использовать аж четыре(!): '#\\\\#', т.к., с учетом экранирования при обработке строки, это не что иное как #\\#.

Таким образом, строка '\\1', переданная как часть шаблона, в действительности будет работать как \1.
В то же время, строка '\1' дойдет без изменений: т.к. символ 1 не является в PHP служебным при декларации строк, слэш сохранится; поэтому в PHP строки '#(.)\1+#s' и '#(.)\\1+#s' в качестве шаблонов PCRE эквивалентны.

По той же причине сам слэш можно захватить и рег. выражением с тремя, а не четырьмя слэшами: '#\\\#' - такое будет работать.
Однако, последовательность, содержащая вслед за слэшем какой-нибудь символ, являющийся в PCRE служебным и потому требующий в шаблоне экранирования, потребует рег. выражения, где на слэш выделено четыре слэша: например, ловим фрагмент \?. Для этого понадобится шаблон '#\\\\\?#' - целых пять слэшей! Четыре - на сам слэш и ещё один - чтобы экранировать знак вопроса. С учетом экранирования внутри строк PHP, это будет #\\\?#, что с учетом экранирования PCRE соответствует захвату последовательности \?
Если попытаться на слэш выделить не четыре, а три, т.е. использовать '#\\\\?#' (три на слэш + один на знак вопроса), то из последовательности \? будет захвачен только слэш, т.е. знак вопроса останется за бортом. Вот почему это происходит: '#\\\\?#' есть, с учетом экранирования строк, #\\?#; первый слэш экранирует специальный символ, за ним идущий - второй слэш, в результате чего он теряет специальное значение; далее следует знак вопроса, который оказывается ничем не экранирован и специального значения своего не теряет, действуя в таком случае как квантификатор {0,1}. Т.е. шаблон #\\?# соответствует строке, состоящей из нуля или одного слэша (это если не принимать во внимание жадность квантификаторов. но этого вопроса касаться здесь не будем). Таким образом, совпадение прекращается в лучшем случае после захвата слэша и не включает знак вопроса.

Вот, так вот и получается.

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

P.S. Окинул взглядом написанное и понял, что изложено очень запутанно. Но тема правда такая, что нормально объяснить трудно...
То, что не убивает нас, делает нас инвалидами.
18.07.2008, 02:06
Ответить

Serg_pnz

Нормально написано - сюжет понятен. Только всё равно код у меня работает если 2 слеша ставить :)
18.07.2008, 15:28
Ответить

1234ru

Это оттого, что Вы использовали двойные кавычки: "#(.)\1+#s". Внутри двойных кавычек последовательность \1 воспринимается как декларация символа с ASCII-кодом 01 (это непечатаемый символ: попробуйте echo "\1";). Поэтому у Вас строка вообще не захватывалась (ибо захватываться таким шаблоном должна строка, состоящая из любого символа, за котором следует непечатный символ \01).
Когда Вы добавили второй слэш, он сэкранировал и стоящий следом, в результате чего тот утратил своё специальное значение и перестал, грубо говоря, взаимодействовать с цифрой.

Внутри одинарных кавычек в PHP служебные последовательности теряют своё специальное значение, и использование '#(.)\1+#s' позволит нам добиться желаемого результата.

(а я про это, кстати, забыл; у меня в примере для Вас тоже были двойные кавычки - сейчас пример исправил, а то еще кто-нибудь неправильно посмотрит)


По тем же причинам при составлении для preg_replace() строки замены также лучше использовать одинарные кавычки и не забывать про специальное значение слэша (разумеется) и знака доллара ($).

На всякией случай: про различные виды кавычек есть страница в руководстве по PHP.
То, что не убивает нас, делает нас инвалидами.
20.07.2008, 08:13
Ответить

Serg_pnz

1234ru, большое-пребольшое спасибо!
21.07.2008, 11:53
Ответить
NO USERPIC

AlexNZ

Во! Грамотно и всё "по полочкам". Очень важная инфа.
Хочу добавить, что preg_... называются Perl совместимыми, но на практике они несовместимы.
Для того что бы поймать слэш в строке '\abc'
В PHP нужно написать '/\\\\/'
В Perl нужно только /\\/ (обратите внимание, в Perl regexp не заключено в кавычки)
Причины подробно описаны в статье, спасибо.

И еще, помимо синтаксиса регулярных выражений, есть и другое отличие.
Perl использует для regexp недетерминированный конечный автомат, а PHP использует детерминированный конечный автомат как для ereg_... так и для preg_...
Чем это кончается? А результаты поиска могут (и не редко) отличаться. А если вы ожидаете true/false, то и отличия могут быть диаметрально противоположны. :-)
06.08.2008, 10:41
Ответить

1234ru

AlexNZ
Perl использует для regexp недетерминированный конечный автомат, а PHP использует детерминированный конечный автомат как для ereg_... так и для preg_...

AlexNZ
результаты поиска могут (и не редко) отличаться

Вот это да. Интересно.
А как это на практике может выглядеть?
(к сожалению, знания о конечных автоматах ограничиваются прочтением двух страниц wikipedia, поэтому я был бы Вам признателен, если бы Вы пример привели)


То, что не убивает нас, делает нас инвалидами.
06.08.2008, 17:38
Ответить
NO USERPIC

AlexNZ

Для начала еще одна особенность PHP и Perl
В PHP рег. выражения - функция (набор функций)
В Perl это оператор (тоже набор операторов - m, s, tr)
Без объяснений понятно, что это важно. :-)

Теперь о НКА и ДКА. Мир не стоит на месте и прошлым вечером я в этом опять убедился.
С чего бы начать... :-)
Тесты которые сильно различали regexp Perl и PHP теперь не проходят.
Вот тест, который раньше проходил.
строка =XX========================================
regexp /X(.+)+X/ или /X(.+)*X/
для ДКА выдает сразу,
классический НКА при нашей жизни работу не завершит.
Однако Perl легко с этим справился, налицо работа оптимизатора, как его обойти я пока не придумал.
Да, вот еще. Второй regexp вызывает в Perl нарушение работы механизма regexp, если написать так:
print /X(.+)*X/;
но внутри if() всё пройдет нормально.

Еще.
Задача обработки make-файла. Строка может продолжаться на нескольких строках, для обозначения продолжения в конце физической строки стоит \
$str = "SRC=array.c button.c eval.c \
missing.c version.c"
;

Допустим дело происходит на *nix системе, т.е. перенос это только "\n". Примеры для regexp, где точка не совпадает с "\n".
\w+=.* - найдет только первую строку, без продолжения
/^(\w+=.*\\\n.*)/ - должно найти все строки, но НКА не должен найти, таков его движок, а вот ДКА найдет, поскольку обязан найти самое длинное совпадение.
Есть еще POSIX НКА, этот тоже должен найти.
Сегодняшние PHP и Perl находят обе строки.
Можно предположить, что оба они используют НКА версии POSIX. Сильно доверять этому не стоит - мы смотрим на мир regexp через "кривые" очки оптимизаторов. :-)

Могу предположить, что ранее я зря принял ergexp PHP как ДКА.

Насколько же это один движок - про различия. Смотрим следующий код.

PHP:
$str = '=XX========================================';

if(preg_match('/X(.*)+X/', $str)) { print 1; }
else { print 0; }

if(preg_match('/X(.*)*X/', $str)) { print 1; }
else { print 0; }


Ответит: 00

и Perl:
my $_ = '=XX========================================';

if(/X(.*)+X/) { print 1; }
else { print 0; }

if(/X(.*)*X/) { print 1; }
else { print 0;}


Ответит: 11

Приехали... Ответы оказались противоположны.

Если удалить квантификаторы после (.*) т.е. /X(.*)X/ - результаты будут идентичны.

А теперь приятное. Светлое будущее PHP.
ereg(), eregi() а также ereg_replace(), ereg_replacei() исчезнут в PHP версии 6. Разработчики рекомендуют использовать preg_match() и preg_replace() соответственно.
Это не единственные изменения в PHP, читайте об этом: http://www.ibm.com/developerworks/library/os-php-future/index.html?ca=drs-

Ой, чуть не забыл. Порекомендую книжку "Регулярные выражения" Дж. Фридл (O'Relly, Питер)
07.08.2008, 08:43
Ответить
NO USERPIC

rgbeast

Очень понравилось по ссылке:

Features that will be removed from the PHP version include:
* magic_quotes
* register_globals
* register_long_arrays
* safe_mode

Давно бы уже, а то приходится людей учить как забарывать эти кавычки и register_globals http://webew.ru/articles/198.webew
07.08.2008, 14:33
Ответить
NO USERPIC

AlexNZ

Ну register_globals можно просто игнорировать, а magic_quotes можно забивать так:
function & kill_magic_quotes(&$str)
{
    if(is_array($str))
    {
        while(list($key, $val) = each($str))
        {
            $str[$key] = kill_magic_quotes($val);
        }
    }
    else
    {
        $str = stripslashes($str);
    }   
    return $str;
}

if(get_magic_quotes_gpc())
{
    kill_magic_quotes($_GET);
    kill_magic_quotes($_POST);
    kill_magic_quotes($_COOKIE);
    kill_magic_quotes($_REQUEST);
}

07.08.2008, 16:15
Ответить

1234ru

Цитата:
Строка может продолжаться на нескольких строках, для обозначения продолжения в конце физической строки стоит \
$str = "SRC=array.c button.c eval.c \
missing.c version.c";

Допустим дело происходит на *nix системе, т.е. перенос это только "\n". Примеры для regexp, где точка не совпадает с "\n".
\w+=.* - найдет только первую строку, без продолжения
/^(\w+=.*\\\n.*)/ - должно найти все строки, но НКА не должен найти, таков его движок


Есть альтернативное мнение насчёт причин вышеописанного поведения: вроде бы, точка считается любым символом, кроме перевода строки, если только не используется модификатор 's' (PCRE_DOT_ALL):
http://ru.php.net/manual/ru/reference.pcre.pattern.modifiers.php

<?php

$str = "SRC=array.c button.c eval.c \
missing.c version.c"
;

preg_match('/\w+=.*/s', $str, $m);
echo ($str == $m[0]); // выведет 1

?>


Насчёт /X(.*)+X/ в PHP. Может быть, это работа оптимизатора - он должен следить за использованием подмасок с квантификаторами:

Можно конструировать бесконечные циклы, указав после шаблона, не содержащегося в заданной строке, квантификатор, не имеющий верхнего предела, например: (a?)*

Ранние версии Perl и PCRE выдавали ошибку во время компиляции для таких шаблонов. Однако, поскольку бывают случаи, когда подобные шаблоны могли бы быть полезны, поддержка таких шаблонов была добавлена. Но если любое повторение такой подмаски фактически не совпадает ни с какими символами, цикл принудительно прерывается.


Вот, видимо, оптимизатор и заглючил..
В любом случае, есть наблюдение, что использование шаблона с модификатором жадности, напротив, приводит к совпадению:


<?php

$str = '=XX========================================';
echo (int) preg_match('/X(.*)+X/', $str); // выведет 0
echo (int) preg_match('/X(.*?)+X/', $str); // выведет 1

?>


Цитата:
Порекомендую книжку "Регулярные выражения" Дж. Фридл (O'Relly, Питер)

Да, надо бы заняться, видно, что вещь хорошая (лежит в электронном виде, никак не возьмусь...).
То, что не убивает нас, делает нас инвалидами.
21.08.2008, 00:51
Ответить

Serg_pnz

if (preg_match_all('#'.$user[1].',#si', $for_sound, $tmp)>0)    echo "<script>soundManager.play('ring');</script>";
if (preg_match_all("#\*DRINK\*#is", $for_sound, $tmp)>0)    echo "<script>soundManager.play('drn1');</script>";
if (preg_match_all("#\*BRAVO\*#is", $for_sound, $tmp)>0)    echo "<script>soundManager.play('applause');</script>";
if (preg_match_all("#\*BYE\*#is", $for_sound, $tmp)>0)  echo "<script>soundManager.play('Goodbye');</script>";
if (preg_match_all("#[:-&gt;#is", $for_sound, $tmp)>0)  echo "<script>soundManager.play('serdit');</script>";
if (preg_match_all("#:-!#is", $for_sound, $tmp)>0)  echo "<script>soundManager.play('sliv');</script>";
if (preg_match_all("#:-\\*#is", $for_sound, $tmp)>0)    echo "<script>soundManager.play('tomno');</script>";


Можно как-то избавится от такого количества проверок?
06.08.2008, 14:26
Ответить

1234ru

Цитата:
Можно как-то избавится от такого количества проверок?

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

Другое дело, что имхо можно код немного "причесать":

1. Использовать preg_match() вместо preg_match_all() (если нужен сам факт совпадения, то первая удобней и легче для компьютера)

2. Повторяющиеся фрагменты убрать.

3. В рег. выражениях кое-где модификаторы лишние, т.к. нет возможности совпадения регистрозависимыми сиволами (модификатор i) или переводом строки (модификатор s).

Получается что-то типа:

if (preg_match('#'.$user[1].',#si', $for_sound))
    $s = 'ring';
if (preg_match("#\*DRINK\*#i", $for_sound))     
    $s = 'drn1';
if (preg_match("#\*BRAVO\*#i", $for_sound))     
    $s = 'applause';
if (preg_match("#\*BYE\*#i", $for_sound))
    $s = 'Goodbye';
if (preg_match("#[:-&gt;#", $for_sound))  
    $s = 'serdit';
if (preg_match("#:-!#", $for_sound))  
    $s = 'sliv';
if (preg_match("#:-\\*#", $for_sound))    
    $s = 'tomno';

echo "<script>soundManager.play('$s');</script>";


Через switch я бы такое переписывать не стал, т.к. алгоритмически тот же перебор вариантов, а чтобы реализовать регистрозависимость, придется предварительно приводить всё к какому-то одному регистру, а для нелатинских символов корректность работы этой операции в PHP под вопросом.

То, что не убивает нас, делает нас инвалидами.
06.08.2008, 18:01
Ответить

Serg_pnz


1234ru, реально помогаешь! Спасибо!
Скоро релиз чата, как мне написать и с какой ссылкой благодарность для тебя (в дистрибе и/или факе)? /*и не спорь, ссылка ДОЛЖНА быть и будет!*/
06.08.2008, 20:11
Ответить

1234ru

Честно говоря, неожиданно польщен :).
Ссылку можно, например, на мой профиль здесь:
http://webew.ru/users/63.webew
То, что не убивает нас, делает нас инвалидами.
07.08.2008, 20:42
Ответить

Serg_pnz

Новая проблема.

У меня есть разбор на смайлы. При чем ;) - это уже устоявшееся выражение.
Пользователь пишет цитату в кавычках и ставит после кавычки скобку - типа улыбнулся.
Пример
а вот смешная "цитата")))


Поскольку в базе кавычки хранятся как сущность &quot;, то декодер выдает смайл подмигивания, чего быть не должно.
Кстати сочетание "D тоже неправильно отрабатывается.

Как бы обойти этот момент?
20.08.2008, 13:39
Ответить

bur

В базе лучше хранить исходный текст сообщения пользователя, т.е. " а не &quot;. Нужно делать htmlspecialchars после запроса из базы, а не при инсерте. Этот подход в целом более правильный и решит вашу проблему.
20.08.2008, 13:49
Ответить

Serg_pnz

и какая разница? достану, прогоню через htmlspecialchars, прогоню через декодер смайлов... тот же "вид с боку"
20.08.2008, 13:52
Ответить

Serg_pnz

Пока вижу выход в смене сущности на уникальную абракадабру, прогон через декодер и обратную смену на сущность...
20.08.2008, 13:55
Ответить

bur

Прогони сначала через смайлопарсер, а потом через htmlspecialchars :-)
20.08.2008, 14:02
Ответить

Serg_pnz

ага, и похерить ссылки на картинки?
20.08.2008, 14:26
Ответить
NO USERPIC

rgbeast

Как вариант:
1. декодер самйлов замениет их на ::SMILE1::
2. htmlspecialchars
3. смайлы заменяются на рисунки
20.08.2008, 14:35
Ответить

1234ru

Цитата:
Поскольку в базе кавычки хранятся как сущность &quot;, то декодер выдает смайл подмигивания, чего быть не должно.

Ловить смайлы так: /(?<!&quot);\)/ - поймает точку с запятой и скобку, перед которой не стоит строка '&quot'.

Цитата:
Кстати сочетание "D тоже неправильно отрабатывается.

Аналогично - /(?<!&quot);D/

А вообще мне тоже нравится вот такой подход:

rgbeast

Как вариант:
1. декодер самйлов замениет их на ::SMILE1::
2. htmlspecialchars
3. смайлы заменяются на рисунки
То, что не убивает нас, делает нас инвалидами.
21.08.2008, 01:44
Ответить

Serg_pnz

1234ru, как всегда на высоте! /(?<!quot);D/ - именно это я и хотел услышать.

А вот подход с htmlspecialchars после доставания из базы мне не нравится, что-то мне кажется, что защита ослабевает и htmlspecialchars надо делать именно перед отправкой в базу.
21.08.2008, 10:26
Ответить

1234ru

Перед отправкой в базу надо делать mysql_escape_string() и ни что иное :)

htmlspecialchars() надо имхо после получения данных из базы перед отдачей конечного HTML.
То, что не убивает нас, делает нас инвалидами.
21.08.2008, 10:30
Ответить
NO USERPIC

rgbeast

Мысль в том, чтобы в базе хранить текст, неподвергнутый модификациям, это приводит к большей сохранности данных в граничных случаях. Хранение в базе чего бы то ни было не понижает безопасность.
21.08.2008, 10:54
Ответить

Serg_pnz

Цель игры: не допустить ввода в поле слов Адmin, admin, adMIN и т.п., при чем с учетом регистра и подмены латинских символов на русские и наоборот.

Имею код
if (preg_match("#[aа][dд][тмm][иi][нhn]|[aа][dд][тмm][иi][нhn][иi][cс][mtт][рpr][aа][mtт][oо][рpr]#i", $tmpunam1)) die();

Сегодня ко мне вошел пользователь AДmin, но не вошел Aдmin
Почему?
12.09.2008, 00:45
Ответить
NO USERPIC

rgbeast

php по умолчанию не знает русского языка. Придется указать явно большие и малые русские буквы. Возможно, Михаил знает как заставить php говорить по русски в регулярных выражениях.
12.09.2008, 01:05
Ответить

1234ru

К сожалению, PCRE в PHP не очень в ладах с русским языком. Хотя движок PCRE может распознать нелатинские буквы именно как буквы:

echo preg_match('/\w/', 'АДМИН'); // выведет 1


, преобразовывать букву в разные регистры он не умеет:

echo preg_match('/админ/i', 'АДМИН'); // выведет 0


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

Хорошо, что кодировка utf-8 - особенная, поскольку считается мировым стандартом, и поддержка для неё добавлена аж в PHP 4 (правда, эта функциональность несовместима с Perl).
Реализована эта поддержка с помощью модификатора 'u':

echo preg_match('/админ/ui', 'АДМИН'); // выведет 1, ура!


Поскольку слово 'админ' является частью слова 'администратор', можно исхитриться и вместо ветки использовать подмаску (я запишу упрощенно):

/админ(истратор)?/


Кстати. А зачем у Вас в третьем символьном классе (и далее кое-где) русская буква 'т'? (это соответствует слову 'адтин') Это так и надо?
То, что не убивает нас, делает нас инвалидами.
12.09.2008, 02:38
Ответить

Serg_pnz

Спасибо, попробую по iu

В некоторых шрифтах т в италике выглядит как m
12.09.2008, 08:36
Ответить

Serg_pnz

Что-то не работает
if (preg_match("#[aа][dд][тмm][иi][нhn]|[aа][dд][тмm][иi][нhn][иi][cс][mtт][рpr][aа][mtт][oо][рpr]#iu", $tmpunam1)) die();


Может из-за начального преобразования?
$tmpunam1 = iconv("UTF-8", "CP1251", $tmpunam1);
12.09.2008, 08:55
Ответить

1234ru

Да, именно из-за преобразования, я думаю.
Модификатор 'u' предписывает обрабатывать шаблон как utf8-строку, что и происходит, однако он, естественно, не может совпасть с нужной строкой в cp1251.
То, что не убивает нас, делает нас инвалидами.
12.09.2008, 12:06
Ответить

Serg_pnz

А если конвертнуть всё в urlencode, поискать и в urldecode?
12.09.2008, 20:24
Ответить
NO USERPIC

rgbeast

лучше преобразуйте регулярное выражение в UTF-8 и примените к непреобразованному сообщению (оно исходно как я понял в UTF-8, а скрипт написан в CP1251)
12.09.2008, 20:44
Ответить

Serg_pnz

Ура-ура! Ники победил, теперь фильтрует. Побёг делать антимат. %)
12.09.2008, 21:15
Ответить

Serg_pnz

Отлично работает! Большое спасибо!!!
12.09.2008, 21:36
Ответить

Serg_pnz

Как составить выражение, чтобы тут "РПАПРРАППАПРРОАРРРПП" осталась только первая "А" и все остальные символы, не равные "А"?
02.12.2008, 11:51
Ответить

1234ru

За один проход не получится, придется в несколько стадий.

Один из подходов: сначала первую А заменить на какой-нибудь маркер, который в тексте точно не встречается (например, непечатаемый символ какой-нибудь), потом убрать все оставшиеся А, после чего вернуть первый А:

<?php

$str = 'РПАПРРАППАПРРОАРРРПП';
$result = preg_replace('/А/', "\x01", $str, 1);
$result = preg_replace('/А/', '', $result);
$result = preg_replace("/\x01/", 'А', $result);
echo $result; // выведет 'РПАПРРПППРРОРРРПП'

?>
То, что не убивает нас, делает нас инвалидами.
02.12.2008, 13:32
Ответить

Serg_pnz

Спасибо. Пользуюсь сам этим
            $tmp = explode (".", $sum);
            $buf = $tmp[0];
            unset($tmp[0]);
            $tmp = implode("", $tmp);

Получил первую часть до разделителя в $buf и остаток в $tmp. Далее опять всякие преобразования... В общем цель игры: заменить все тире и запятые на точки и учитывать только первый знак, как разделитель десятичной дроби.

Вся функция
            $sum = preg_replace("# #si", "", $_GET['m1']);
            $sum = preg_replace("#[^0-9-,\.]#si", "", $sum);
            $sum = preg_replace("#[-,]#si", ".", $sum);
            $tmp = explode (".", $sum);
            $buf = $tmp[0];
            unset($tmp[0]);
            $tmp = implode("", $tmp);
            $sum1 = preg_match_all("#(.){1,1}#si", $tmp, $tmp1);
            $sum1 = pow(10, $sum1);
            $m1 = $buf +  $tmp/$sum1;


По идее ваш вариант будет повыгоднее по нагрузке.
02.12.2008, 14:12
Ответить

1234ru

А что вначале есть? (т.е. в чём нужно производить замену?).

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

Кстати: не очень мне понятен смысл выражения #(.){1,1}#si - это, вроде как, любой единичный символ... Или я ошибаюсь?
То, что не убивает нас, делает нас инвалидами.
02.12.2008, 23:26
Ответить

Serg_pnz

Функция принимает данные из формы (не смотрите на GET - так надо)
Данные эти представляют собой число, вводимое оператором при наборе базы, условно - это некоторое десятичное число.
Ориентируясь на собственный опыт, знаю, что тысячи проще набивать с разделителем знаков (пробелом), а вот десятичную запятую - это для сберегания моих нервов (то точка, то запятая выводится, часто ошибаешься, приходится переключать раскладку...) В конечном итоге я ввел, что и дефисом можно отделять десятичную часть.
Но! При вводе большого количества данных, есть вероятность двойного нажатия на запятую (ну зарапотавался оператор) и поэтому функция учитывает только первый введеный знак, остальные игнорируя.
Пусть оператор ввел число 12,56,36 (вторая запятая вылезла при ошибочном нажатии на "3")
Что я делаю: зпт и дефисы меняю на точки - что бы база поняла, что это число. Разбиваю на массив, объеденяя всё, кроме нулевого элемента, получил два числа: 12 и 5636. Этим "#(.){1,1}#si" меряю длину второго элемента, что бы потом правильно записать десятичную дробь.

PS: Кстати, пока писал, вспомнил, что есть функция, измеряющая длину строки, но я не ищу легких путей :D
03.12.2008, 08:40
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: скачать российский ВПН на сайте