Сложное (?) Регулярное выражение соответствия имени для vBulletin - PullRequest
1 голос
/ 14 октября 2011

Я создаю свой собственный BBcode для форума. Я пытаюсь понять правильное выражение, но оно ускользает от меня уже несколько недель. Любые советы экспертов приветствуются.

Пример ввода (очень простой пример):

[quote=Bob]I like Candace. She is nice.[/quote]

Ashley Ryan Thomas

По сути, я хочу заключить любые имена (из указанного списка) в [user] [/ user] BBcode ... кроме, конечно, тех, которые указаны в кавычках, потому что это приводит к ужасным ошибкам синтаксического анализа.

Желаемый вывод:

[quote=Bob]I like [user]Candace[/user]. She is nice.[/quote]

[user]Ashley[/user] [user]Ryan[/user] [user]Thomas[/user]

Мой текущий код:

 $searchArray = array(
 '/(?i)([^=]|\b|\s|\/|\r|\n|\t|^)(Ashley|Bob|Candace|Ryan|Thomas)(\s|\r|\n|\t|,|\.(\b|\s|\.|$)|;|:|\'|"|-|!|\?|\)|\/|\[|$)/'
 );

 $replaceArray = array(
   "\\1[user]\\2[/user]\\3"
 );

 $text = preg_replace($searchArray, $replaceArray, $input);

Что он в настоящее время производит:

 [quote=Bob]I like [user]Candace[/user]. She is nice.[/quote]

 [user]Ashley[/user] Ryan [user]Thomas[/user]

Обратите внимание, что Райан не инкапсулирован тегами [user]. Также обратите внимание, что большая часть дополнительных символов соответствия регулярному выражению добавлялась по мере необходимости по мере их появления на форумах, поэтому удаление их просто приведет к невозможности сопоставления в других ситуациях (т. Е. Нет-нет). Если, конечно, вы не обнаружите явную ошибку в самом регулярном выражении, в этом случае, пожалуйста, укажите на это.

Правда, любая помощь будет принята с благодарностью! Спасибо.

Ответы [ 2 ]

1 голос
/ 14 октября 2011

Это просто, что вы сопоставляете разделители (\s|\r|...) на обоих концах искомых имен. Бедные Ashley и Ryan разделяют один пробел в вашей тестовой строке. Но регулярное выражение может соответствовать ему только один раз - в виде левой или правой границы.

Решение здесь заключается в использовании утверждений. Заключите левый список в (?<= ), а правый в (?= ), чтобы они стали:

 (?<=[^=]|\b|\s|\/|^)
 (?=\s|,|\.(\b|\s|\.|$)|;|:|\'|"|-|!|\?|\)|\/|\[|$)

Кстати, \s уже содержит \r|\n|\t, так что вы, вероятно, можете удалить это.

0 голосов
/ 14 октября 2011

Поскольку вам не нужно совпадать с пробелами с обеих сторон (просто убедитесь, что они есть, верно?), Попробуйте заменить поисковое выражение следующим образом:

$searchArray = array(
  '/\b(Ashley|Bob|Candace|Ryan|Thomas)\b/i'
);

$replaceArray = array(
 '[user]$1[/user]'
);

$text = preg_replace($searchArray, $replaceArray, $input);
...