vBulletin的复杂(?)名称匹配正则表达式

时间:2011-10-14 18:35:30

标签: php regex match vbulletin

我正在为论坛创建一些自定义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]

请注意,Ryan未由[user]标记封装。另请注意,大多数额外的正则表达式匹配字符是在论坛上出现时根据需要添加的,因此删除它们只会使其在其他情况下无法匹配(即禁止否)。当然,除非你在正则表达式中发现了明显的错误,否则请指出它。

但是,真的,非常感谢任何帮助!谢谢。

2 个答案:

答案 0 :(得分:1)

很简单,您在搜索名称的两端匹配分隔符(\s|\r|...)。穷人AshleyRyan在测试字符串中共享一个空格字符。但正则表达式只能匹配一次 - 作为左边界或右边界。

这里的解决方案是使用断言。将左侧列表包含在(?<= )中,将右侧列入(?= ),以便它们变为:

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

顺便说一下,\s已包含\r|\n|\t,因此您可以将其删除。

答案 1 :(得分:0)

因为你真的不需要匹配任何一方的空格(只是确保它们在那里,对吗?)尝试用以下代码替换你的搜索表达式:

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

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

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