Запрошен опыт работы с PHP preg_replace

#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);