markimax Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 (змінено) Задача:Есть краткое описание с bbcode тегами Надо: обрезать описание по определенному количеству символов не трогая теги (т. е сохранив разметку) Если бы задача стояла убрать теги и обрезать описание - всё было бы тривиально просто $amount = 4; $text = "0<img src='image.jpg'>12<b>3</b>456789"; $pattern = ('/((.*?)\S){0,' . $amount . '}/isu'); preg_match_all($pattern, strip_tags(html_entity_decode($text, ENT_QUOTES, 'UTF-8')), $out); $outtext = $out[0][0]; Результат: 0123 (без разметки и тегов) Но надо сделать тоже самое при этом сохранив теги (разметку). Например: обрезать описание до 4 символов (при этом не трогая теги, т.е. оставить разметку)Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании" И второй вариант с учетом того что внутри тегов Помогите составить паттерн для preg_match_all(), потому что ушло много времени, решить то я её решу, вот только времени жалко, уже много потратил. На stackoverflow встали в ступор Хорошая задачка для развития мозгов, да и для ocStore неплохая, например для обрезания краткого описания товаров в списке, с сохранением разметки Я вот думаю, можно ли вообще решить данную задачу регулярными выражениями? Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль один , и на второй 490 рублей, итого = 1280 рублей, призовой фонд. UPD: Задача решена, элегантное решение найдено, призовой фонд остался у автора. Уже используется здесь Решение задачи здесь Змінено 31 березня 2014 користувачем markimax Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Сомневаюсь, что одной регуляркой можно обойтись. Хотя опыта у меня мало. Посмотрите http://stackoverflow.com/questions/9042975/shortening-text-tweet-like-without-cutting-links-inside может поможет. По сути такая же задача. Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Я вот думаю, можно ли вообще решить данную задачу регулярными выражениями? Я редко вопросы задаю, обычно решение нахожу сам, но здесь я перебрал все варианты моих знаний по регулярным выражениям, но так ответа и не нашел ;( Получается не простая задача, взаимоисключающая результаты: не учитывать в квантификации текста (количества символов для "обрезания") теги и что в них, но включить их в результат на своих позициях Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надо теги и что в них оставить as is (т.е. разметку не трогаем), а квантификацию сделать за пределами тегов и обрезать согласно квантификации, но в результате теги и что в них должны присутствовать Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
halfhope Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Сомневаюсь, что одной регуляркой можно обойтись. Хотя опыта у меня мало. Посмотрите http://stackoverflow.com/questions/9042975/shortening-text-tweet-like-without-cutting-links-inside может поможет. По сути такая же задача. Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Я вот думаю, можно ли вообще решить данную задачу регулярными выражениями? Я редко вопросы задаю, обычно решение нахожу сам, но здесь я перебрал все варианты моих знаний по регулярным выражениям, но так ответа и не нашел ;( Получается не простая задача, взаимоисключающая результаты: не учитывать в квантификации текста (количества символов для "обрезания") теги и что в них, но включить их в результат на своих позициях Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надо теги и что в них оставить as is (т.е. разметку не трогаем), а квантификацию сделать за пределами тегов и обрезать согласно квантификации, но в результате теги и что в них должны присутствовать Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
halfhope Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Я вот думаю, можно ли вообще решить данную задачу регулярными выражениями? Я редко вопросы задаю, обычно решение нахожу сам, но здесь я перебрал все варианты моих знаний по регулярным выражениям, но так ответа и не нашел ;( Получается не простая задача, взаимоисключающая результаты: не учитывать в квантификации текста (количества символов для "обрезания") теги и что в них, но включить их в результат на своих позициях Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надо теги и что в них оставить as is (т.е. разметку не трогаем), а квантификацию сделать за пределами тегов и обрезать согласно квантификации, но в результате теги и что в них должны присутствовать Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Я вот думаю, можно ли вообще решить данную задачу регулярными выражениями? Я редко вопросы задаю, обычно решение нахожу сам, но здесь я перебрал все варианты моих знаний по регулярным выражениям, но так ответа и не нашел ;( Получается не простая задача, взаимоисключающая результаты: не учитывать в квантификации текста (количества символов для "обрезания") теги и что в них, но включить их в результат на своих позициях Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надо теги и что в них оставить as is (т.е. разметку не трогаем), а квантификацию сделать за пределами тегов и обрезать согласно квантификации, но в результате теги и что в них должны присутствовать Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Как бы сделал я (не профи в PHP). Обрезал бы строку, потом удалил/закрыл все незакрытые теги. Либо обрезал бы текст больше (до открытия последнего тега) Надо теги и что в них оставить as is (т.е. разметку не трогаем), а квантификацию сделать за пределами тегов и обрезать согласно квантификации, но в результате теги и что в них должны присутствовать Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Кто найдет элегантное решение данной задачи (лучше конечно регулярным выражением) заплачу 790 рублей лицензией на модуль А то эта "тривиальная" задача отняла много времени, которого к сожалению мало Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 Даже если регулярка и получится, то это будет такой убойный монстр... Т.е. под конкртный pattern еще можно что-то прикрутить, а универсальное - увы... ьольше времени уйдет на тестирование. Ок - тогда рассмотрим элегантное решение другими способами. призовой фонд 790 рублей остается в силе ;) Если получиться очень элегантное - добавлю еще 490 рублей лицензией на этот модуль :) Итого призовой фонд - 1280 рублей Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
freelancer Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер.к тому же, эти bb-коды наверняка как-то экранирутся? Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 березня 2014 Автор Share Опубліковано: 20 березня 2014 одной регуляркой не обойтись, нужно писать парсер. к тому же, эти bb-коды наверняка как-то экранирутся? Как раз с ними легче, все они в [tag]..[/tag] Кстати для ocStore тоже полезно обрезать краткое описание товаров оставляя разметку html посимвольно, по словам и по предложеням Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
chukcha Опубліковано: 20 березня 2014 Share Опубліковано: 20 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 ТЗ не полное :) Что обрезаем, где, как, в каких тегах? 1. Исходник 2. Результат Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Надіслати Поділитися на інших сайтах More sharing options... halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
halfhope Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Все же написал в первом посту Обрезать текст до 4 символов (теги (разметка) сохраняются, но после 4-го символа удаляются) Текст: 0[img=image.jpg]12[b]3[/b]456789 Должен быть результат: 0[img=image.jpg]12[b]3[/b]4 Т.е. 01234 вместе с тегами, т.е. тот что внутри тегов не учитывается в "обрезании", как и сами теги Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 ТЗ неполное, пример неполный Что мы должны считать? количество символов plaintext Вход: 12[img=image1][b]23[/b][img=image2]все равно обрежется результат: 12[img=image1][b]23[/b][img=image2]или 12[img=image1][b]345[/b][img=image2]все равно обрежется результат: 12[img=image1][b]34[/b][img=image2] Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 21 березня 2014 Автор Share Опубліковано: 21 березня 2014 Так обычный plaintext так и обрежется. Задам наводящие вопросы для раскрытия темы: Как должна вести себя обрезка, если символ, по который нужно обрезать находится внутри тега. Т.е. 0[img=image.jpg]12[b]3 Он должен его обрезать до: 0[img=image.jpg]12 или все же закрыть тег 0[img=image.jpg]12[b]3[/b] Еще я так понял, что теги img должны обрабатываться как какой-то объект длинной в один символ. Или весь текст внутри тегов должен обрабатываться как объект длинной в один символ? Все что в тегах - сохраняется в result (я описывал задачу) Т е результат будет для обрезания до 4-х символов 0[img=image.jpg]12[b]3[/b]4 1 23 4 (количество) Надіслати Поділитися на інших сайтах More sharing options... chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000 × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
chukcha Опубліковано: 21 березня 2014 Share Опубліковано: 21 березня 2014 Делаем 1. Получаем список всех [tag]...[/tag] 2. получаем позиции тегов и меняем их на уникальные ### 3. replace уникальных комбинаций ### на '' 4. обрезаем полученную строку 6. вставляем в строку в нужные места тега по запомненным позицмям. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення PRICE MASTER - Модуль імпорту/експорту товарів, парсинг, переклад, генерація текстів, редактор каталогу та багато іншого Автор: ScriptBrains 1.0 Синхронізація Замовлень Rozetka.ua та Opencart Автор: sinco Product Manipulator Автор: Hiperlynx007 Видалення дублікатів товарів для OpenCart Автор: Hatshypsut Вибір категорій і виробників для "Знайшли дешевше" шаблону Upstore Автор: Flint2000
markimax Опубліковано: 28 березня 2014 Автор Share Опубліковано: 28 березня 2014 Решение задачи (UTF-8): <?php header('Content-Type: text/html; charset=utf-8'); function utf8_strlen($string) { return strlen(utf8_decode($string)); } function utf8_substr($string, $offset, $length = null) { // generates E_NOTICE // for PHP4 objects, but not PHP5 objects $string = (string)$string; $offset = (int)$offset; if (!is_null($length)) { $length = (int)$length; } // handle trivial cases if ($length === 0) { return ''; } if ($offset < 0 && $length < 0 && $length < $offset) { return ''; } // normalise negative offsets (we could use a tail // anchored pattern, but they are horribly slow!) if ($offset < 0) { $strlen = strlen(utf8_decode($string)); $offset = $strlen + $offset; if ($offset < 0) { $offset = 0; } } $Op = ''; $Lp = ''; // establish a pattern for offset, a // non-captured group equal in length to offset if ($offset > 0) { $Ox = (int)($offset / 65535); $Oy = $offset%65535; if ($Ox) { $Op = '(?:.{65535}){' . $Ox . '}'; } $Op = '^(?:' . $Op . '.{' . $Oy . '})'; } else { $Op = '^'; } // establish a pattern for length if (is_null($length)) { $Lp = '(.*)$'; } else { if (!isset($strlen)) { $strlen = strlen(utf8_decode($string)); } // another trivial case if ($offset > $strlen) { return ''; } if ($length > 0) { $length = min($strlen - $offset, $length); $Lx = (int)($length / 65535); $Ly = $length % 65535; // negative length requires a captured group // of length characters if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(' . $Lp . '.{' . $Ly . '})'; } elseif ($length < 0) { if ($length < ($offset - $strlen)) { return ''; } $Lx = (int)((-$length) / 65535); $Ly = (-$length)%65535; // negative length requires ... capture everything // except a group of -length characters // anchored at the tail-end of the string if ($Lx) { $Lp = '(?:.{65535}){' . $Lx . '}'; } $Lp = '(.*)(?:' . $Lp . '.{' . $Ly . '})$'; } } if (!preg_match( '#' . $Op . $Lp . '#us', $string, $match)) { return ''; } return $match[1]; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } function utf8_preg_match_all( $ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = 'UTF-8' ) { // WARNING! - All this function does is to correct offsets, nothing else: //(code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER) $pn_offset = strlen(utf8_substr($ps_subject, 0, $pn_offset, $ps_encoding)); $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset); if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE)){ foreach($pa_matches as &$ha_match) foreach($ha_match as &$ha_match) if (isset($ha_match[1])) $ha_match[1] = utf8_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding); } return $ret; } $source = 'М23[img]http://site[/img]122[img=http://site]3456789[img=http://site]33 33'; $limit = 5; $counter = 0; $matches = array(); echo $source . "<br>"; utf8_preg_match_all('/(?:\[.*\].*\[\/.*\])|(.)/Usiu', $source, $matches, PREG_OFFSET_CAPTURE); foreach($matches[1] as $num=>$val) { if(is_array($val)) { $counter++; if($counter == $limit) { $source = utf8_substr_replace($source, '', $val[1] + 1); break; } } } echo $source . "<br>"; ?> Меняя в паттерне (.) на (\x20) - будет обрезаться по словам, на (\.) - по количеству предложений P.S. двух функций нет в хелпере utf8.php opencart- а, это utf8_substr_replace() и utf8_preg_match_all(). Почему надо было использовать utf8_preg_match_all() а не стандартный я могу объяснить кому интересно (намекну, стандартная функция смещение считает в байтах, а в UTF-8 на символ приходиться пара байт, поэтому смещение второго символа кириллицы - это 4 :ugeek: , поэтому и пришлось использовать новую пользовательскую функцию, так что аккуратнее со смещениями в UTF-8 и флага PREG_OFFSET_CAPTURE, грабли еще те). Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам [Решено] Регулярные выражения: обрезать текст, по определенному количеству символов, с тегами не "трогая" теги
markimax Опубліковано: 31 березня 2014 Автор Share Опубліковано: 31 березня 2014 Модераторы - поставьте в заголовке темы "Решено" и удалите этот пост :) Я бы даже зафиксировал тему, так как нервных клеток было потрачено много, как и времени, решений на stackoverflow и т.п форумах нет, зато на opencartforum есть, а используется часто в разработке. Надіслати Поділитися на інших сайтах More sharing options... freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0 Перейти до списку тем Схожі публікації [Решено] vqmod regex Автор: zebratratata, 28 березня 2015 vqmod regex 9 відповідей 1 544 перегляди zebratratata 28 березня 2015 vqmod multiline regex Автор: halfhope, 23 жовтня 2014 vqmod multiline (і ще %d) Теги: vqmod multiline regex 4 відповіді 1 410 переглядів halfhope 23 жовтня 2014 Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку
freelancer Опубліковано: 31 березня 2014 Share Опубліковано: 31 березня 2014 ппа Надіслати Поділитися на інших сайтах More sharing options... Ця тема закрита для публікації повідомлень. Share More sharing options... Передплатники 0
Recommended Posts