|
|
|
|
#(?<=[\W])(?<!(<a[^>]*>)){$keyWord}(?=[\W])#i
|
ругается:
Warning: preg_replace() [function.preg-replace]: Compilation failed: lookbehind assertion is not fixed length at offset 14
|
нужно сделать так, чтобы слева от слова, был не словестный символ и оно не находилось бы уже в теге <A>...
заранее спасибо!) | |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 12:22)
| | > (?<!(<a[^>]*>))
в "заглядывающих назад" подмасках нельзя использовать квантификаторы типа *+, только если какие-нибудь {3}
С такими непонятными сложными условиями как будто надо что-то типа
(<a\b[^>]*>)?(?(1)(?!)|(\b$keyWord\b))
(?!) делает совпадение ошибочным
(?(1)если|или) проверяет было-ли $1
но такое тоже работает медленно, чем например было-бы
"#<a\b[^>]*>\w+|(\b$keyWord\b)#"
т.к. при несовпадении в конце шаблона сравнение снова начинается с "начало"+1 | |
|
|
|
|
|
|
|
для: heed
(28.01.2010 в 17:19)
| | Может вы тогда подскажете, возможно я не в правильную сторону думаю?
как заменить правильно эти выражения?
#квартир\w*#i
#квартир\w* посуточно#
|
тоесть чтобы не получилось в итоге:
<a href="http://localhost/apartments2" target="_blank" class="keyword"><a href="http://localhost/apartments" target="_blank" class="keyword">квартиры</a> посуточно</a>
|
зы. в обоих ваших примерах не учитывается условие если слово уже в ссылке и получается не нужное выше:) | |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 18:53)
| | не понял, чего у меня не получилось, там только (<a\b[^>]*>)?(?(1)(?!)|(\b$keyWord\b)) вроде должно было делать то что нужно , (только с другими номерами подмасок) но я ещё пока не тестил :)
если насчёт проверок (?<=\W)и(?=\W), то того-же самого можно просто \b , если в $keyWord по краям символы слов.
а это наверное одним выражением лучше
#квартир\w*(?:\s+посуточно)?# | |
|
|
|
|
|
|
|
для: heed
(28.01.2010 в 20:02)
| | #квартир\w*(?:\s+посуточно)?#
ну это никчему вроде :)
словосочетание задаётся точно, через форму пользователем как ключевое слово :)
а вот нащёт того что уже в теге, совсем х3..:( | |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 20:29)
| | насчёт тегов кажется понял, не нужно в тегах <a></a> парсить
, а насчёт ввода пользователем не понял.
Пользователю чего вообще должно быть можно вводить из символов, чтобы это безнаказанно попало в выражение ?
всмысле "два слова" "т р и слова " или вообще регулярные выражения?
и по html-файлу чего с найденными словами нужно сделать? | |
|
|
|
|
|
|
|
для: heed
(28.01.2010 в 21:06)
| | ну пользователю можно вводить только "\w+"
остальное убираю preg_quote и т.д.
символ % заменяю на \w*
а дальше идёт замена составленого выражения из слова на
<a href="#" class=\"keyword\">$0</a>
ну пользователь пока я:)) это для админки, поэтому ничего левого быть не может :)
для начала хотелось бы разобраться с самим выражением:) | |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 21:49)
| | всёравно не понял, если текст заменяется по просто тексту одним preg_replace()
, то чем не устраивает например простое выражение
<form action="" method="post">
<input type="text" name="re" value="с%"/>
<input type="submit" value="x"/>
</form><pre><?php
$txt = '
ну пользователю можно вводить только "\w+"
остальное убираю preg_quote и т.д.
символ % заменяю на \w*
а дальше идёт замена составленого выражения из слова
';
$re = '';
echo (isset($_POST['re'])
&& ($re =str_replace('%', '\w*', preg_quote( trim($_POST['re']), '#'))))
? preg_replace('#\b'. $re .'\b#i', '<a href="#" class="keyword">$0</a>', $txt)
: $txt;
echo "\n\n\n". '#\b'. $re .'\b#i'
. "\n\n\n". '#(<a\b[^>]*>)?(?(1)(?!)|\b'. $re .'\b)#i';
| только не учёл magic_quotes , и вообще думаю что нужно от пользовательского ввода оставить только \w и %
или ессли введено два слова идёт поиск каждого по очереди? | |
|
|
|
|
|
|
|
для: heed
(28.01.2010 в 22:32)
| | ну слова вводятся в текстареа и каждая новая строка = новое слово и в preg_replace суётся массив выражений. Так что такой вариант не прокатит 6) | |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 12:22)
| | Если я правильно понял самый первый вопрос
>нужно сделать так, чтобы слева от слова, был не словестный символ и оно не находилось бы уже в теге <A>...
предлагаю следующий вариант
#<a(?:(?!\b$keyWord\b)[^>])*>.*?(?<=[\W])($keyWord).*?</a>#i
|
| |
|
|
|
|
|
|
|
для: sl1p
(28.01.2010 в 12:22)
| | тогда наверное только как-нибудь так
<form action="" method="post">
<textarea name="re">
с%
hr%
а%
</textarea>
<input type="submit" value="x"/>
</form><pre><?php
$txt = '
ну пользователю можно вводить только "\w+"
остальное убираю preg_quote и т.д.
href
символ % заменяю на \w*
а дальше идёт замена составленого выражения из слова
';
function linker($m){
return ($m[0]{0} == '<') ? $m[0] : '<a href="#">'. $m[0] .'</a>';
}
if(isset($_POST['re'])) {
$re = split("[[:space:]]*\n[[:space:]]*"
, str_replace('%', '\w*', preg_quote( trim($_POST['re']), '#')));
print_r($re);
foreach($re AS $k => $v) {
if ($v === '') {
unset($re[$k]); break;
}
if (!$k) $re[$k] = '#\b'. $v .'\b#i';
else $re[$k] = '#<a\b[^>]*>[^<]*</a\s*>|\b'. $v .'\b#i';
echo "\n". htmlspecialchars($re[$k]);
}
if ($re[0]) $txt = preg_replace_callback($re, 'linker', $txt);
}
echo $txt;
|
вместо foreaach можно array_walk() какой-нибудь прикрутить
и с (<a\b[^>]*>)?(?(1)..... это работало только если сразу в <a> шло слово
, а чтобы какое-нибудь href не захавало похоже ещё сложнее чего-нибудь вставлять
//upd
хотя такой ещё вариант
<?php
$txt = '
<a href="#">x - символ</a>
y - символ
';
echo preg_replace('#\bсимв\w+\b(?!(?:(?!<a\b).[^<]*)*</a\b)#', '<a href="#">$0</a>', $txt);
|
| |
|
|
|
|
|
|
|
для: heed
(29.01.2010 в 12:05)
| | выражение: #<a\b[^>]*>[^<]*</a\s*>|\b'. $v .'\b#i
порадовало :)
но теперь получилась такая штука:
#квартир\w*#i
#квартир\w* посуточно#
|
<a href="http://localhost/apartments" target="_blank" class="keyword">квартиры</a> <a href="http://localhost/apartments" target="_blank" class="keyword">КваРтира</a>
<a href="http://localhost/apartments" target="_blank" class="keyword"><a href="http://localhost/apartments2" target="_blank" class="keyword">квартиры посуточно</a></a> | |
|
|
|
|
|
|
|
для: sl1p
(29.01.2010 в 13:13)
| | >#квартир\w*#i
>#квартир\w* посуточно#
Так тут надо просто стазу определяться какие квартиры нужнее ,) посуточные или понесуточные :)
Если посуточные запосуточнить раньше чем непосуточные , то непосуточные понезапосуточнятся.
И там в массиве просто первое выражение урезанное.
//upd
и кажется split() вроде покушались с шестой версии php транклютировать , если я правильно понял что такое ereg-функции. | |
|
|
|
|
|
|
|
для: heed
(29.01.2010 в 13:19)
| | посуточные запосуточнить
таких слов не может быть :)если вы не например а про мой вариант.
могут быть "квартиры посуточно", "квартира посуточно" и оно должно быть важнее чем просто "квартир\w*"..
вот. | |
|
|
|
|
|
|
|
для: sl1p
(29.01.2010 в 15:09)
| | если нужно чтобы вводить можно было по разному, можно попробовать по длиннам строк уполрядочмвать
function lencmp($a, $b)
{
if (strlen($a) == strlen($b)) {
return 0;
}
return (strlen($a) > strlen($b)) ? -1 : 1;
}
$arr = array('#кварт\w*#i', '#квартир\w*#i', '#квартир\w* посуточно#');
usort($arr, 'lencmp');
print_r($arr);
|
| |
|
|
|
|
|
|
|
для: heed
(29.01.2010 в 15:58)
| | так а какая разница в каком порядке слова в массиве?)
всё равно ведь заменяет.. | |
|
|
|