正则表达式模式提取引号

时间:2011-05-27 16:28:24

标签: php regex

在我的网站上切换辩论论坛的代码,我将更改引号存储在数据库中的方式。现在我需要提出一个正则表达式来重新排列我的数据库中已提交的帖子。

以下是我当前辩论文章如何存储在数据库中的示例(引号用引号括起来)。注意:为了说明,我缩进了它:

Just citing a post
[quote]Text of quote #3
       [quote]Text of quote #2
              [quote]Text of quote #1
                     [name]User 1[/name]
              [/quote]
              [name]User 2[/name]
       [/quote]
       [name]User 3[/name]
[/quote]

我现在想要的是,前者将重新排列为这样:

Just citing a post
[quote:User 3]
      Text of quote #3
      [quote:User 2]
           Text of quote #2
           [quote:User 1]
                 Text of quote #1
           [/quote]  
      [/quote]   
[/quote]

你们有没有人能指出我如何用正则表达式做到这一点?我正在使用PHP。

提前致谢,感谢您的帮助:)

4 个答案:

答案 0 :(得分:1)

此功能可以完成这项工作。它以递归方式从最内层引用重新格式化到最外层引用:

function reformat($str) {
  while (preg_match('#\[quote\](.+)\[name\](.+)\[/name\]\s*\[/quote\]#Us',
         $str, 
         $matches)) {
    $str = str_replace($matches[0], 
                       '[quote:'.$matches[2].']'.$matches[1].'[/quote]',
                       $str);
  }
  return $str; 
}

行动中:

$before = "Just citing a post
  [quote]Text of quote #3
    [quote]Text of quote #2
      [quote]Text of quote #1
        [name]User 1[/name]
      [/quote]
      [name]User 2[/name]
    [/quote]
    [name]User 3[/name]
  [/quote]";

echo reformat($before);

输出:

Just citing a post
  [quote:User 3]Text of quote #3
    [quote:User 2]Text of quote #2
      [quote:User 1]Text of quote #1
        [/quote]
      [/quote]
    [/quote]

答案 1 :(得分:1)

这样做:

$input = "Just citing a post
[quote]Text of quote #3
       [quote]Text of quote #2
              [quote]Text of quote #1
                     [name]User 1[/name]
              [/quote]
              [name]User 2[/name]
       [/quote]
       [name]User 3[/name]
[/quote]";

function fix_quotes($string) {
    $regexp = '`(\s*)\[quote\]((?:[^\[]|\[(?!quote\]))*?)\[name\](.*?)\[\/name\]\s*\[\/quote\]`';
    while (preg_match($regexp, $string)) {
        $string = preg_replace_callback($regexp, function($match) {
            return $match[1] . '[quote:' . $match[3] . ']' . trim(fix_quotes($match[2])) . $match[1] . '[/quote]';
        }, $string);
    }
    return $string;
}

echo fix_quotes($input);

结果:

Just citing a post
[quote:User 3]Text of quote #3
       [quote:User 2]Text of quote #2
              [quote:User 1]Text of quote #1
              [/quote]
       [/quote]
[/quote]

编辑:还没有看到joelhardi已经发布了类似的解决方案,而且他看起来更清洁所以我坚持他的解决方案:)

答案 2 :(得分:0)

不要使用正则表达式。您所谈论的内容本质上是XML的变异,而regex is not the right tool for parsing XML.您需要做的就是编写解析器。

但是,我建议使用实际的XML代替。它已经存在,它是标准化的,语法几乎完全相同,并且已经有很多解析器。我从这里开始:

编辑:只是为了说明这可以轻松成为有效的XML:

<quote src="User 3">
      Text of quote #3
      <quote src="User 2">
           Text of quote #2
           <quote src="User 1">
                 Text of quote #1
           </quote>  
      </quote>   
</quote>

答案 3 :(得分:0)

由于此处涉及的复杂性(您将需要条件,以及“匹配/替换所有”功能),我建议只在Regex中执行此操作。使用具有严格正则表达式功能的编程语言,并将Regex与此语言结合使用以执行您想要的操作。我推荐PHP。