Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

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

 

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

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

тема: Парсинг текста
 
 автор: SkyFree   (07.01.2014 в 13:17)   письмо автору
 
 

Есть например текст "А я иду шагаю по **луне**" подскажите как звездочки возле слова луна заменить на html код <strong> </strong> ?

  Ответить  
 
 автор: psychomc   (07.01.2014 в 13:55)   письмо автору
 
   для: SkyFree   (07.01.2014 в 13:17)
 

preg_replace

  Ответить  
 
 автор: Stasyn   (07.01.2014 в 14:44)   письмо автору
 
   для: psychomc   (07.01.2014 в 13:55)
 

Можно также воспользоваться строковой функцией str_replace.

  Ответить  
 
 автор: Deed   (07.01.2014 в 14:49)   письмо автору
 
   для: Stasyn   (07.01.2014 в 14:44)
 

Нельзя.

  Ответить  
 
 автор: Stasyn   (07.01.2014 в 14:51)   письмо автору
 
   для: Deed   (07.01.2014 в 14:49)
 

Это почему же нельзя?

  Ответить  
 
 автор: Deed   (07.01.2014 в 15:04)   письмо автору
 
   для: Stasyn   (07.01.2014 в 14:51)
 

Можно, только в случае безвариантности **луне**. Если же вместо "луне" будет друга последовательность символов - без регулярки не обойтись:
http://codepad.org/uOtSZmuS

  Ответить  
 
 автор: confirm   (07.01.2014 в 15:05)   письмо автору
 
   для: Deed   (07.01.2014 в 15:04)
 

Вы уверены, что не обойтись?

  Ответить  
 
 автор: Deed   (07.01.2014 в 15:12)   письмо автору
 
   для: confirm   (07.01.2014 в 15:05)
 

Буду рад всему новому!
callback?

  Ответить  
 
 автор: confirm   (07.01.2014 в 15:17)   письмо автору
 
   для: Deed   (07.01.2014 в 15:12)
 

А что такое callback?

  Ответить  
 
 автор: Deed   (07.01.2014 в 15:23)   письмо автору
 
   для: confirm   (07.01.2014 в 15:17)
 

Да подумал, что ребе Сураски уже прикурочил к str_replace() какую-нибудь функцию обратного вызова.

  Ответить  
 
 автор: confirm   (07.01.2014 в 15:33)   письмо автору
 
   для: Deed   (07.01.2014 в 15:23)
 

Не надо никаких str_replace() и прочего.

  Ответить  
 
 автор: confirm   (07.01.2014 в 14:51)   письмо автору
 
   для: Deed   (07.01.2014 в 14:49)
 

Можно

  Ответить  
 
 автор: Deed   (07.01.2014 в 15:40)   письмо автору
 
   для: confirm   (07.01.2014 в 14:51)
 

Как?

  Ответить  
 
 автор: confirm   (07.01.2014 в 15:43)   письмо автору
 
   для: Deed   (07.01.2014 в 15:40)
 

Думайте, вы же заявили, что никак, а это не так.

  Ответить  
 
 автор: Deed   (07.01.2014 в 15:49)   письмо автору
 
   для: confirm   (07.01.2014 в 15:43)
 

И речь по-прежнему о str_replace(), так?

  Ответить  
 
 автор: confirm   (07.01.2014 в 15:57)   письмо автору
 
   для: Deed   (07.01.2014 в 15:49)
 

Зачем, что кроме ее больше ничего в РНР нет?

  Ответить  
 
 автор: Deed   (07.01.2014 в 16:03)   письмо автору
 
   для: confirm   (07.01.2014 в 15:57)
 

Но здесь я сказал "Нельзя" именно с помощью str_replace().
И присел пример с регуляркой.
А о других вариантах я даже не подозреваю. Честно.

  Ответить  
 
 автор: confirm   (07.01.2014 в 16:06)   письмо автору
 
   для: Deed   (07.01.2014 в 16:03)
 

> Если же вместо "луне" будет друга последовательность символов - без регулярки не обойтись:

<?
$s 
'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$pst strpos($s'*') ? 1;
$s explode('**'$s);
foreach(
$s as $k=>$v$s[$k] = $k $pst '<b>'.$v.'</b>' $v;

echo 
implode($s);

  Ответить  
 
 автор: Deed   (07.01.2014 в 16:20)   письмо автору
 
   для: confirm   (07.01.2014 в 16:06)
 

Я даже не знаю, что это такое - $k & 1 ^ $pst . Без иронии.
Буду рад объяснению.

  Ответить  
 
 автор: confirm   (07.01.2014 в 16:26)   письмо автору
 
   для: Deed   (07.01.2014 в 16:20)
 

Это вы просто обязаны знать, так как это не только в РНР имеется.
http://www.php.net/manual/ru/language.operators.bitwise.php

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:07)   письмо автору
 
   для: confirm   (07.01.2014 в 16:26)
 

Спасибо, мэтр!
Я, к своему стыду, никогда и нигде не использовал побитовое сравнение, и, признаться, не совсем пока "въехал" в его суть. Нужно будет разобраться.
Но вот, что бросилось в глаза:

 <?
$s 
'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s explode('**'$s);
foreach(
$s as $k=>$v$s[$k] = $k%2!='<b>'.$v.'</b>' $v;
echo 
implode($s); 
?>

А ниже ваш код ну просто очень остроумен! Я об учитывании расположения пробелов.
Нет предела совершенству!
Еще раз спасибо!

  Ответить  
 
 автор: confirm   (07.01.2014 в 18:14)   письмо автору
 
   для: Deed   (07.01.2014 в 18:07)
 

Деление это арифметическая операция, а тем более деление по модулю, с анализом остатка. А битовые операции, это логические операции выполняющие быстрее, к тому же, еще не факт, что $k % 2, это то что нужно, ибо звездочкой текст может и начинаться. Да и !($k % 2), это короче.

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:20)   письмо автору
 
   для: confirm   (07.01.2014 в 18:14)
 

Никакой проблемы с начальными звездочками нет - первый элемент массива будет пустой и только.
Мне очень трудно уловить суть этих смещений вправо-влево.

  Ответить  
 
 автор: confirm   (07.01.2014 в 18:28)   письмо автору
 
   для: Deed   (07.01.2014 в 18:20)
 

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

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:28)   письмо автору
 
   для: confirm   (07.01.2014 в 18:14)
 

Можно "разжевать" словами этот фрагмент "$k & 1 ^ $pst"?
То есть, если "*" в строке присутствует, $pst = strpos($s, '*') ? 0 : 1; переменной $pst присваиваем значение, равное 0.
Дальше выполняем это сравнение: $k & 1 ^ 0 - что здесь происходит?

  Ответить  
 
 автор: confirm   (07.01.2014 в 18:34)   письмо автору
 
   для: Deed   (07.01.2014 в 18:28)
 

Если пустой элемент не проблема, то можно ничего не выяснять, а значит проверять надо на четность. У всех четных элементов младший разряд содержит 1, и если проверять этот бит, то и....
если $k & 1 = 1, четное
если $k & 1 = 0, нечетное

Битовое И часто применяют как маску, для выделения необходимого, а XOR, для установки/сброса битов. По ссылке же описаны эти операции, а так же их приоритет.

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:41)   письмо автору
 
   для: confirm   (07.01.2014 в 18:34)
 

Премного благодарен!
Буду разбираться.

  Ответить  
 
 автор: Stasyn   (08.01.2014 в 15:21)   письмо автору
 
   для: confirm   (07.01.2014 в 16:06)
 

Спасибо отличный пример, не как не мог найти применение оператору &, в условие $pst = strpos($s, '*') !== false? 0 : 1; я бы добавил проверку на неравенство false.

  Ответить  
 
 автор: confirm   (08.01.2014 в 17:26)   письмо автору
 
   для: Stasyn   (08.01.2014 в 15:21)
 

Вы можете работать двояко - с "чистыми" данными, это значит пустые элементы полученные после разбиения выбросить. В этом случае нужно знать с какого элемента, с четного или нет нужно обрамлять текст. Либо пренебрегаем этим (не мешают пустые элементы), то просто всегда проверяем на четность.
Не то чтобы лень мне все было писать, просто некогда было, да и разговор то шел не о том как именно все закончено должно выглядеть, а просто о возможностях, поэтому не счел нужным "распространятся". Можно и подробнее:

1. "Чистота данных". Добавлять в условие тождественную проверку смыла нет для этого примера. Так как обусловливается, что разбивать текст нужно обязательно, а значит важно знать больше нуля или нулевое смещение имеет символ разделения. Если же действительно применять это на практике, то есть определять содержит ли текст необходимое для замены или нет, то да нужна тождественная проверка, чтобы это выяснить, но только для этого.

Если смещение больше нуля, то будет проверяться четный бит операцией XOR, поэтому $pst устанавливается равным 0, в противном случае 1. (Можно и иначе, просто в дальнейшей операции нужно инвертировать результат)

<?
$s 
'**еще** слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
//$s = 'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$pst strpos($s'*') ? 1;
//удалим пустые элементы и сбросим индексы
$s array_values(array_diff(explode('**'$s),['']));
//если маска индекса массива с проверкой бита положительная, обрамляем элемент
//а получается так
//для нечетных  0 & 1 ^ 1 = 1 - строка начиналась с разделителя
//для четных    1 & 0 ^ 1 = 1 - разделитель имеет смещение больше нуля   
foreach($s as $k=>$v$s[$k] = $k $pst '<b>'.$v.'</b>' $v;


2. Просто замена и соединение. Для этого не надо проверок в строке, а просто разбиваем на массив, при этом элементы которые надо обрамлять всегда будут четными, а значит:

<?
foreach($s as $k=>$v$s[$k] = $k '<b>'.$v.'</b>' $v;


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

  Ответить  
 
 автор: Stasyn   (08.01.2014 в 19:17)   письмо автору
 
   для: confirm   (08.01.2014 в 17:26)
 

Большое вам спасибо за объяснение.

  Ответить  
 
 автор: confirm   (08.01.2014 в 20:45)   письмо автору
 
   для: Stasyn   (08.01.2014 в 19:17)
 

Ну тогда еще одно решение:

<?
define
("RUS_SUMB","йцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ*");
$s '**еще** слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s str_word_count($s1RUS_SUMB); //или разбить по пробелу
foreach($s as $k=>$v$s[$k] = $v[0]=='*' '<b>'.trim($v'*').'</b>' $v;
echo 
implode(' '$s);

  Ответить  
 
 автор: confirm   (07.01.2014 в 17:48)   письмо автору
 
   для: Deed   (07.01.2014 в 16:03)
 

А это str_replace():

<?
$s 
'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s str_replace([' **''** '], [' <b>''</b> '], $s);
echo 
$s;

  Ответить  
 
 автор: psychomc   (07.01.2014 в 18:39)   письмо автору
 
   для: confirm   (07.01.2014 в 17:48)
 

красиво, но не катит же для слов в начале и конце строки. имхо, регулярка как-то изящнее будет чем вот это всё.

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:42)   письмо автору
 
   для: psychomc   (07.01.2014 в 18:39)
 

Эти примеры представлены для демонстрации.

  Ответить  
 
 автор: confirm   (07.01.2014 в 18:45)   письмо автору
 
   для: psychomc   (07.01.2014 в 18:39)
 

А какая проблема дополнить пробелами? Собственно не в этом дело, просто когда заявляют, что без рег. считай смерть, это значит, что "по сторонам смотреть" не привыкли. А решать надо не изяществом, в смысле красоты, а иным подходом.

  Ответить  
 
 автор: Deed   (07.01.2014 в 18:49)   письмо автору
 
   для: confirm   (07.01.2014 в 18:45)
 

Нужно ли понимать, что в глубине своего механизма регулярки оперируют теми же строковыми функциями?

  Ответить  
 
 автор: confirm   (07.01.2014 в 19:15)   письмо автору
 
   для: Deed   (07.01.2014 в 18:49)
 

Нет, это не так, рег выражения это иной механизм.

  Ответить  
 
 автор: psychomc   (07.01.2014 в 18:54)   письмо автору
 
   для: confirm   (07.01.2014 в 18:45)
 

а каким в данном случае будет иной подход? регулярка тут даст краткость, а что даст всё остальное? неужели речь о приросте производительности?

  Ответить  
 
 автор: Deed   (07.01.2014 в 19:02)   письмо автору
 
   для: psychomc   (07.01.2014 в 18:54)
 

Мы обсуждали чисто "академический" аспект альтернативного решения вопроса без привязки рассмотрения прочих нюансов. То есть, были, прежде всего, продемонстрированы возможности php.

  Ответить  
 
 автор: confirm   (07.01.2014 в 19:07)   письмо автору
 
   для: psychomc   (07.01.2014 в 18:54)
 

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

  Ответить  
 
 автор: psychomc   (07.01.2014 в 19:14)   письмо автору
 
   для: confirm   (07.01.2014 в 19:07)
 

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

  Ответить  
 
 автор: confirm   (07.01.2014 в 19:18)   письмо автору
 
   для: psychomc   (07.01.2014 в 19:14)
 

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

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

  Ответить  
 
 автор: psychomc   (07.01.2014 в 20:07)   письмо автору
 
   для: confirm   (07.01.2014 в 19:18)
 

ну в первом для строки:

**слово** слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово **слово**

результат получился

<b></b>слово<b> слово </b>раз<b> слово слово слово слово </b>два<b> слово слово слово слово слово </b>три<b> слово слово </b>слово<b></b>

  Ответить  
 
 автор: confirm   (07.01.2014 в 20:24)   письмо автору
 
   для: psychomc   (07.01.2014 в 20:07)
 

Ну если в лоб то да, а если нет, то не получится.

  Ответить  
 
 автор: SkyFree   (07.01.2014 в 15:30)   письмо автору
 
   для: psychomc   (07.01.2014 в 13:55)
 

Ох ну получилось вроде бы) спасибо всем

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

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