#php #regex #arrays #preg-replace
#php #регулярное выражение #массивы #preg-заменить
Вопрос:
Я создаю некоторый пользовательский BBCode для форума. Я пытаюсь правильно использовать регулярное выражение, но оно ускользает от меня уже два дня. Приветствуется любая экспертная консультация.
Входные данные (например, пример сообщения на форуме):
[quote=Bob]Мне нравится Кэндис. Она милая.[/quote]
Я согласен, она очень милая. Мне тоже нравится Эшли, и особенно [Райан], когда он выпивает.
По сути, я хочу поместить любые имена (из указанного списка) в [user] [/user] BBCode … за исключением, конечно, тех, которые заключены в кавычки, потому что это приводит к некоторым ужасным ошибкам синтаксического анализа. Ниже приведен пример того, каким я хочу видеть результат.
Желаемый результат:
[quote=Bob]Мне нравится [пользователь] Кэндис[/user]. Она милая.[/quote]
Я согласен, она очень милая. Мне тоже нравится [пользователь] Эшли[/user], и особенно [[пользователь] Райан[/user]], когда он выпивает.
Мой текущий код:
$searchArray = array(
'/(?i)(Ashley|Bob|Candace|Ryan|Tim)/'
);
$replaceArray = array(
"[user]\0[/user]"
);
$text = preg_replace($searchArray, $replaceArray, $input);
$input, конечно, устанавливается на содержимое публикации (то есть на первый пример, приведенный выше). Как я могу достичь желаемых результатов? Я не хочу, чтобы регулярное выражение совпадало, когда имени предшествует знак равенства (=), но если поместить [^=] перед именами в регулярном выражении, оно будет соответствовать любому символу, отличному от знака равенства (т. Е. пробелам), что затем испортит форматирование.
Обновить
Проблема в том, что при использовании 1 вместо перед именами пропускается первый символ (потому что сопоставляется все, что угодно, кроме =). Вывод приводит к этому:
[quote=Bob]Мне нравится[пользователь] Кэндис[/user]. Она милая.[/quote]
Я согласен, она очень милая. Мне тоже нравится [пользователь] Эшли[/user], и особенно [пользователь] Райан[/user]], когда он выпивает.
Комментарии:
1. Это было бы довольно простым решением, если бы я мог каким-то образом изменить обратную ссылку 0 с помощью таких вещей, как PHP функция substr, но если я установлю переменной значение 0, а затем заменю эту переменную в replaceArray(), обратный вызов не будет затронут. Я не разбираюсь в регулярных выражениях. 🙁
2. Вы ищете границы слов? regular-expressions.info/wordboundaries.html
Ответ №1:
Вы были на правильном пути с [^=]
идеей. Вы можете поместить его вне группы захвата, и вместо \0
того, которое соответствует полностью, используйте \1
и \2
, т. е. первую и вторую группы захвата
$searchArray = array(
'/(?i)([^=])(Ashley|Bob|Candace|Ryan|Tim)/'
);
$replaceArray = array(
"\1[user]\2[/user]"
);
$text = preg_replace($searchArray, $replaceArray, $input);