正则表达式有所不同

时间:2012-02-07 07:49:55

标签: php regex

正则表达式问题

我有处理图形文件的正则表达式代码。

$view[content] = preg_replace("/(\<img )([^\>]*)(\>)/i", "\\1 name='target_resize_image[]' onclick='image_window(this)' style='cursor:pointer;' \\2 \\3", $view[content]);

在网页上,如果html代码上没有'style',这段代码工作正常。但如果有“style”,则“style”代码改为“style ='cursor:pointer;”。 / p>

我知道,如果在img中有“style ='...'”,则添加style ='...'“。如果没有,”style“代码应为”style ='cursor:pointer ;'”

“preg_replace”在img代码中删除了“style ='aaaaaa'”。那应该是“style ='cursor:pointer'”。

代码输入

<img style="border-bottom: medium none; border-left: medium none; width: 160px; float: left; height: 160px; border-top: medium none; margin-right: 1em; border-right: medium none" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" /> 

代码输出

<img style="cursor:pointer" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" /> 

代码 - 应该是

<img style="cursor:pointer;border-bottom: medium none; border-left: medium none; width: 160px; float: left; height: 160px; border-top: medium none; margin-right: 1em; border-right: medium none" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" /> 

任何有用的评论都将不胜感激。

1 个答案:

答案 0 :(得分:4)

你的正则表达式创建了这个输出:

<img name='target_resize_image[]' onclick='image_window(this)' style='cursor:pointer;' style="border-bottom: medium none; border-left: medium none; width: 160px; float: left; height: 160px; border-top: medium none; margin-right: 1em; border-right: medium none" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" / >

请注意,您在此字符串中有两个样式属性。显然你使用了某种HTML验证,它通过删除第二个来自动“修复”这个,然后只留下style='cursor:pointer;'

可以改善你的正则表达式。使用/(alt|style|src)=("[^"]*")/ipreg_match_all这样的模式,您可以提取img标记的属性,然后对其进行操作并从中构建新的HTML字符串。

无论如何,我建议不要使用RegExp的来操纵HTML。使用DOM工具更简单,更健壮。看看Simple HTML DOM Parser。这个简单的代码

require 'simple_html_dom.php'; // http://simplehtmldom.sourceforge.net/
$html = str_get_html($img); // load HTML as DOM object
$img = $html->find('img', 0); // find your tag
$img->style = "cursor:pointer;".$img->style; // manipulate the style attr
$img->name="target_resize_image[]"; // set other attr's
$img->onclick="image_window(this)";
echo htmlspecialchars($html); // output HTML as string

为您提供输出

<img style="cursor:pointer;border-bottom: medium none; border-left: medium none; width: 160px; float: left; height: 160px; border-top: medium none; margin-right: 1em; border-right: medium none" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" name="target_resize_image[]" onclick="image_window(this)" />

瞧!它不依赖于属性的顺序,使用的引号,空格和换行符。

编辑:WindStory已请求非DOM解决方案

解决方案在很大程度上取决于输入字符串的给定strcuture。例如,如果您确定每个给定的img已经具有style属性,则可以使用普通替换来执行此操作:

$img = str_replace('style="', 'style="cursor:pointer; ', $img); // add info to the given style-attr
$img = str_replace('<img', '<img new_attribute="value" ', $img); // add new attrs

对给定标记的保证较少,您可以使用上面提到的RegExp从img标记中提取属性

// extract attr's, depends on double quotes
$Attrs = array();
if (preg_match_all('/(alt|style|src)="([^"]*)"/i', $img, $matches, PREG_SET_ORDER)) {
    foreach ($matches as $match) {
        $Attrs[$match[1]] = $match[2];
    }
}

// change/add attr's
$Attrs['style'] = empty($Attrs['style']) ? 'cursor:pointer' : 'cursor:pointer; '.$Attrs['style'];
$Attrs['name'] = 'target_resize_image[]';
$Attrs['onclick'] = 'image_window(this)';

// build new HTML
$new_img = '<img ';
foreach ($Attrs as $key => $value) $new_img .= $key.'="'.$value.'" ';
$new_img .= '/>';

在行动here中查看。

希望有所帮助。

编辑2:WindStory要求提供更容错的RegExp解决方案

这是一个小函数,用于在给定的HTML字符串中添加/更改属性。它支持attribtues的单引号或双引号,但没有缺失的引号,如果单引号用双引号括起来,则不起作用,反之亦然。

function add_attr($html, $name, $value, $append = null) {
    $attr_pattern = "/\b({$name}=['\"])([^'\"]*)(['\"])/i";
    if (preg_match($attr_pattern, $html, $regs)) {
        if (!is_null($append)) {
            $value = $regs[2].$append.$value;
        }
        $replace = "\\1$value\\3";
        $html = preg_replace($attr_pattern, $replace, $html);
    } else {
        $tag_pattern = '/<[\w]+\b/i';
        $replace = "\\0 $name=\"$value\"";
        $html = preg_replace($tag_pattern, $replace, $html);
    }
    return $html;
}

将{html-Tag插入$html,定义属性的$name并定义$value。如果该属性已存在,则将替换该值,否则将添加该值。如果您设置$append,则会附加$value$append将用作连接符号。

$img = add_attr($img, 'style', 'cursor:pointer', '; ');
$img = add_attr($img, 'name', 'target_resize_image[]');
$img = add_attr($img, 'onclick', 'image_window(this)');
echo htmlspecialchars($img);

将结束

<img onclick="image_window(this)" name="target_resize_image[]" style="border-bottom: medium none; border-left: medium none; width: 160px; float: left; height: 160px; border-top: medium none; margin-right: 1em; border-right: medium none; cursor:pointer;" alt="120131_12e1c8be2d6954ec9a3579ae57a64bfe_3EsTQWri2Zx9.gif" src="/data/cheditor4/1201/120131_02133169e006e1d08fc72fa5ff1e7a25_5KKOd8zrZhluXoqpiN.gif" />