递归使用正则表达式的HTML标记内容

时间:2011-01-31 16:41:08

标签: php regex

我正在为我的客户编写一个应用程序,该应用程序使用WYSIWYG允许员工修改一个字母模板,其中包含某些变量,这些变量被解析为该信函所针对的客户的信息。

WYSIWYG生成我保存到SQL Server数据库的HTML。然后我使用PHP类生成带有模板文本的PDF文档。

这是我的问题。 PDF生成类可以翻译b,u,i HTML标签。而已。这基本上没问题,除了我需要翻译块序列。我认为最好的解决方案是编写一个正则表达式语句,用于获取每个blockquote HTML块的内容,并用五个空格替换块中的每一行。诀窍是一些blockquotes可能包含嵌套的blockquotes(双缩进,什么不是)

但不幸的是,我从来没有精通过正则表达式,我花了最后1.5个小时尝试不同的模式并且没有任何工作。

以下是gotchyas:

  • 字符串可能包含也可能不包含blockquote块
  • 字符串可以包含多个blockquotes
  • String可能包含任何级别的blockquotes blocks嵌套
  • 我们可以依赖正确形成的HTML

示例输入字符串看起来像这样:

Dear Charlie,<br><br>We are contacting you because blah blah blah blah.<br><br><br>To login, please use this information:<blockquote>Username: someUsername<br>Password: somePassword</blockquote><br><br>Thank you.

要简单地解决这个问题,我需要用5个空格替换每个blockquote中的每个HTML中断,然后是\ n换行符。

3 个答案:

答案 0 :(得分:4)

您可能想要检查PHP Simple HTML DOM Parser。您可以使用它来解析HTML DOM树的输入并使用它。

答案 1 :(得分:3)

~<blockquote>((?:[^<]*+(?:(?!<blockquote>)|(?R))*+)*+)</blockquote>~

您需要使用preg_replace_callback递归运行此正则表达式:

const REGEX_BLOCKQUOTE = '~<blockquote>((?:[^<]*+(?:(?!<blockquote>)|(?R))*+)*+)</blockquote>~';
function blockquoteCallback($matches) {
    return doIndent(preg_replace_callback(REGEX_BLOCKQUOTE, __FUNCTION__, $matches[1]));
}

$output = preg_replace_callback(REGEX_BLOCKQUOTE, 'blockQuoteCallback', $input);

我的正则表达式假设,在blockquote或其他任何地方都没有任何属性。

(PS:我会将“使用DOM解析器”评论留给其他人。)

答案 2 :(得分:1)

正则表达式有一个theory behind them,即使现代的常规expresison引擎提供了一个'Type-2.5'级别的语言,有些东西仍然不可行。在您的部分情况下,嵌套是不容易实现的。 解释这个问题的一种简单方法就是说正则表达式无法统计。 即他们无法计算筑巢水平...

你需要的是有限的CFG(paren-counting类型).. 你需要以某种方式保持计数..可能是一个堆栈或树...