2010-12-07 68 views
2

我们刚刚发布了一些代码,以使我们的软件更方便用户使用,并且使用起来很麻烦。基本上,我们试图用<br />标签替换换行符。麻烦的是,有时我们的用户将输入如下代码:压缩HTML标记中的属性之间的空白

<a 
href='http://nowhere.com'>Nowhere</a> 

当我们运行我们的代码,这相当于

<a <br />href='http://nowhere.com' />Nowhere</a> 

这显然不能正常显示。

是否有正则表达式或PHP函数去除或可能压缩HTML标记的属性之间的空白?

澄清:这不是完整的HTML。它与Markdown或其他语言更类似(我们最终将转向Markdown,但我需要快速修复)。所以我不能将它解析为普通的HTML。换行符需要正确转换为<br />标签。

+0

@ajreal - `trim()`只会做字符串的开始和结尾。 – 2010-12-07 18:30:40

回答

1

一些搜索和大量的试验和错误后,我想出了以下解决方案/黑客:

/* 
* Compress all whitespace within HTML tags (including PRE at the moment) 
*/ 
$regexp = "/<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/i"; 

preg_match_all($regexp, $text, $matches); 

foreach($matches[0] as $match) { 
    $new_html = preg_replace('/\s+/', ' ', $match); 
    $text = str_replace($match, $new_html, $text); 
} 

执行此代码后,在$text所有的HTML标签将被正确格式化,并且有效的,没有换行符字符。

我知道这不是最好的解决方案,但它很有效,很快我们就会迁移到真正的标记语言(如Markdown)。

2

您需要一个能够正确解析所有HTML的库,您永远不会知道用户可能发明什么。

HTML Purifier

3

嗯,你为什么要使用的工具时,有没有为此目的设计的HTML格式,让你的自我DOM库。

http://simplehtmldom.sourceforge.net/

+0

我解析的HTML不是有效的,它是HTML内部的文本。所以,HTML的部分必须是有效的,但其余部分只是文本。 – 2010-12-07 18:51:41

+0

那么你有没有实施`
`标签的原始内容?如果是的话,把它放到DOM Parser中,循环投掷每个元素并将属性放在一个新的新标签中,然后将其格式化。 – RobertPitt 2010-12-07 18:59:04

0

理想情况下,你会使用XML解析器,通过DOM和SAX API的。但是,如果您的内容不是正确的XML,而是带有几个标签的纯文本,解析器可能会失败(这取决于所用的工具,我猜)。

针对您的特定问题的粗略解决方案可能如下:构建具有两种状态的状态机,即标记内部和标记外部。您逐字读取输入字符。阅读'<'后,切换到“内部”状态。阅读'>'后,切换到“外部”状态。读完'\ n'后,如果处于“外部”状态,则发出“< br/>”(否则不会发出任何东西)。

这只是一个草图,它可能需要进一步完善。