|
|
|
| Есть например текст "А я иду шагаю по **луне**" подскажите как звездочки возле слова луна заменить на html код <strong> </strong> ? | |
|
|
|
|
|
|
|
для: SkyFree
(07.01.2014 в 13:17)
| | preg_replace | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 13:55)
| | Можно также воспользоваться строковой функцией str_replace. | |
|
|
|
|
|
|
|
для: Stasyn
(07.01.2014 в 14:44)
| | Нельзя. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 14:49)
| | Это почему же нельзя? | |
|
|
|
|
|
|
|
для: Stasyn
(07.01.2014 в 14:51)
| | Можно, только в случае безвариантности **луне**. Если же вместо "луне" будет друга последовательность символов - без регулярки не обойтись:
http://codepad.org/uOtSZmuS | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 15:04)
| | Вы уверены, что не обойтись? | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 15:05)
| | Буду рад всему новому!
callback? | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 15:12)
| | А что такое callback? | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 15:17)
| | Да подумал, что ребе Сураски уже прикурочил к str_replace() какую-нибудь функцию обратного вызова. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 15:23)
| | Не надо никаких str_replace() и прочего. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 14:49)
| | Можно | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 14:51)
| | Как? | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 15:40)
| | Думайте, вы же заявили, что никак, а это не так. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 15:43)
| | И речь по-прежнему о str_replace(), так? | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 15:49)
| | Зачем, что кроме ее больше ничего в РНР нет? | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 15:57)
| | Но здесь я сказал "Нельзя" именно с помощью str_replace().
И присел пример с регуляркой.
А о других вариантах я даже не подозреваю. Честно. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 16:03)
| | > Если же вместо "луне" будет друга последовательность символов - без регулярки не обойтись:
<?
$s = 'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$pst = strpos($s, '*') ? 0 : 1;
$s = explode('**', $s);
foreach($s as $k=>$v) $s[$k] = $k & 1 ^ $pst ? '<b>'.$v.'</b>' : $v;
echo implode($s);
|
| |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 16:06)
| | Я даже не знаю, что это такое - $k & 1 ^ $pst . Без иронии.
Буду рад объяснению. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 16:20)
| | Это вы просто обязаны знать, так как это не только в РНР имеется.
http://www.php.net/manual/ru/language.operators.bitwise.php | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 16:26)
| | Спасибо, мэтр!
Я, к своему стыду, никогда и нигде не использовал побитовое сравнение, и, признаться, не совсем пока "въехал" в его суть. Нужно будет разобраться.
Но вот, что бросилось в глаза:
<?
$s = 'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s = explode('**', $s);
foreach($s as $k=>$v) $s[$k] = $k%2!=0 ? '<b>'.$v.'</b>' : $v;
echo implode($s);
?>
|
А ниже ваш код ну просто очень остроумен! Я об учитывании расположения пробелов.
Нет предела совершенству!
Еще раз спасибо! | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 18:07)
| | Деление это арифметическая операция, а тем более деление по модулю, с анализом остатка. А битовые операции, это логические операции выполняющие быстрее, к тому же, еще не факт, что $k % 2, это то что нужно, ибо звездочкой текст может и начинаться. Да и !($k % 2), это короче. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 18:14)
| | Никакой проблемы с начальными звездочками нет - первый элемент массива будет пустой и только.
Мне очень трудно уловить суть этих смещений вправо-влево. | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 18:20)
| | Ну если с "пустотами" работать, можно и по модулю, но все таки это не тот случай когда деление единственно возможное. Смещений при выделении по маске (логическо И) и проверка бита (исключающиее ИЛИ) никаких нет. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 18:14)
| | Можно "разжевать" словами этот фрагмент "$k & 1 ^ $pst"?
То есть, если "*" в строке присутствует, $pst = strpos($s, '*') ? 0 : 1; переменной $pst присваиваем значение, равное 0.
Дальше выполняем это сравнение: $k & 1 ^ 0 - что здесь происходит? | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 18:28)
| | Если пустой элемент не проблема, то можно ничего не выяснять, а значит проверять надо на четность. У всех четных элементов младший разряд содержит 1, и если проверять этот бит, то и....
если $k & 1 = 1, четное
если $k & 1 = 0, нечетное
Битовое И часто применяют как маску, для выделения необходимого, а XOR, для установки/сброса битов. По ссылке же описаны эти операции, а так же их приоритет. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 18:34)
| | Премного благодарен!
Буду разбираться. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 16:06)
| | Спасибо отличный пример, не как не мог найти применение оператору &, в условие $pst = strpos($s, '*') !== false? 0 : 1; я бы добавил проверку на неравенство false. | |
|
|
|
|
|
|
|
для: Stasyn
(08.01.2014 в 15:21)
| | Вы можете работать двояко - с "чистыми" данными, это значит пустые элементы полученные после разбиения выбросить. В этом случае нужно знать с какого элемента, с четного или нет нужно обрамлять текст. Либо пренебрегаем этим (не мешают пустые элементы), то просто всегда проверяем на четность.
Не то чтобы лень мне все было писать, просто некогда было, да и разговор то шел не о том как именно все закончено должно выглядеть, а просто о возможностях, поэтому не счел нужным "распространятся". Можно и подробнее:
1. "Чистота данных". Добавлять в условие тождественную проверку смыла нет для этого примера. Так как обусловливается, что разбивать текст нужно обязательно, а значит важно знать больше нуля или нулевое смещение имеет символ разделения. Если же действительно применять это на практике, то есть определять содержит ли текст необходимое для замены или нет, то да нужна тождественная проверка, чтобы это выяснить, но только для этого.
Если смещение больше нуля, то будет проверяться четный бит операцией XOR, поэтому $pst устанавливается равным 0, в противном случае 1. (Можно и иначе, просто в дальнейшей операции нужно инвертировать результат)
<?
$s = '**еще** слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
//$s = 'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$pst = strpos($s, '*') ? 0 : 1;
//удалим пустые элементы и сбросим индексы
$s = array_values(array_diff(explode('**', $s),['']));
//если маска индекса массива с проверкой бита положительная, обрамляем элемент
//а получается так
//для нечетных 0 & 1 ^ 1 = 1 - строка начиналась с разделителя
//для четных 1 & 0 ^ 1 = 1 - разделитель имеет смещение больше нуля
foreach($s as $k=>$v) $s[$k] = $k & 1 ^ $pst ? '<b>'.$v.'</b>' : $v;
|
2. Просто замена и соединение. Для этого не надо проверок в строке, а просто разбиваем на массив, при этом элементы которые надо обрамлять всегда будут четными, а значит:
<?
foreach($s as $k=>$v) $s[$k] = $k & 1 ? '<b>'.$v.'</b>' : $v;
|
Не обязательно и сохранять массив, можно сразу формировать строку в цикле. Необязательно разбивать, не обязательно и str_replace(), решить можно и по иному, если говорить "можно ли"? Конечно можно, например, можем мы мысленно представить входную строку как набор битов, единичные биты которой это символы, а нулевые биты замещаемые символы? Конечно можем, и, если пропустить эту последовательность через регистр, на выходе которого будет триггер определяющий ноль, то можно реагировать на появление нуля, а также какое положение в последовательности он занимает. А описать это, но уже программно тоже не проблема - если строка это элементы массива, то пройдясь циклом (регистр) по строке получаем каждый элемент, и если это символ (единица), то просто запоминаем, если замещаемый символ (ноль), то проверяем четный ли он по счету или нет (триггер), и замещаем соответствующим. | |
|
|
|
|
|
|
|
для: confirm
(08.01.2014 в 17:26)
| | Большое вам спасибо за объяснение. | |
|
|
|
|
|
|
|
для: Stasyn
(08.01.2014 в 19:17)
| | Ну тогда еще одно решение:
<?
define("RUS_SUMB","йцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ*");
$s = '**еще** слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s = str_word_count($s, 1, RUS_SUMB); //или разбить по пробелу
foreach($s as $k=>$v) $s[$k] = $v[0]=='*' ? '<b>'.trim($v, '*').'</b>' : $v;
echo implode(' ', $s);
|
| |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 16:03)
| | А это str_replace():
<?
$s = 'слово слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово слово';
$s = str_replace([' **', '** '], [' <b>', '</b> '], $s);
echo $s;
|
| |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 17:48)
| | красиво, но не катит же для слов в начале и конце строки. имхо, регулярка как-то изящнее будет чем вот это всё. | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 18:39)
| | Эти примеры представлены для демонстрации. | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 18:39)
| | А какая проблема дополнить пробелами? Собственно не в этом дело, просто когда заявляют, что без рег. считай смерть, это значит, что "по сторонам смотреть" не привыкли. А решать надо не изяществом, в смысле красоты, а иным подходом. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 18:45)
| | Нужно ли понимать, что в глубине своего механизма регулярки оперируют теми же строковыми функциями? | |
|
|
|
|
|
|
|
для: Deed
(07.01.2014 в 18:49)
| | Нет, это не так, рег выражения это иной механизм. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 18:45)
| | а каким в данном случае будет иной подход? регулярка тут даст краткость, а что даст всё остальное? неужели речь о приросте производительности? | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 18:54)
| | Мы обсуждали чисто "академический" аспект альтернативного решения вопроса без привязки рассмотрения прочих нюансов. То есть, были, прежде всего, продемонстрированы возможности php. | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 18:54)
| | Да причем тут производительность, хотя за краткостью может скрываться и прожорливость. Это как раз тогда, когда по всем пустякам и применяют рег. выражения, хотя выгоднее применять стандартные функции.
Самое плохое, это привычка думать "шаблоном", хуже этого быть не может, от этой привычки и порождена уверенность, что только рег. выражениями, а других способов нет. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 19:07)
| | это всё понятно, конечно лучше по возможности использовать простые строковые функции. просто конкретно этот пример кажется неудачным. т.е уже достаточно много телодвижений и пока что ни одно решение полностью не удовлетворяет условию
*точнее нет удовлетворяет, но удовлетворять не будет при переносе **луне** в начало или в конец | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 19:14)
| | Например несколько операций CISC процессора могут быть записаны в одном машинном слове, а RISC процессору придется это объяснять кучей инструкций. Да, первое выглядит "изящно" и "круто", но второе обшлепает первое по скорости за милую душу. Но никто не отказывается ни от первой, ни от второй архитектуры, каждая занимает свою нишу под свои задачи, там, где она выгодна.
Тоже самое и здесь. Это всего лишь примеры к дискуссии, не более, хотя первое полностью удовлетворяет, и второе можно сделать таковым. | |
|
|
|
|
|
|
|
для: confirm
(07.01.2014 в 19:18)
| | ну в первом для строки:
**слово** слово **раз** слово слово слово слово **два** слово слово слово слово слово **три** слово слово **слово**
|
результат получился
<b></b>слово<b> слово </b>раз<b> слово слово слово слово </b>два<b> слово слово слово слово слово </b>три<b> слово слово </b>слово<b></b>
|
| |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 20:07)
| | Ну если в лоб то да, а если нет, то не получится. | |
|
|
|
|
|
|
|
для: psychomc
(07.01.2014 в 13:55)
| | Ох ну получилось вроде бы) спасибо всем | |
|
|
|