Нужно написать регулярное выражение которое бы обрезало у тегов (за исключением некоторых) все свойства (атрибуты) - т.е. чтобы на выходе были просто чистые теги к примеру есть строка HTML: <p align="left" style="font-size:9pt;" onclock="exit();">абзац</p> а на выходе после регулярки получаем: HTML: <p>абзац</p> но необходимо некоторые теги исключать из такой обрезки к примеру теги <img src="" aling="left"><a href=""> не трогать
Код (Text): <?php ini_set('display_errors',1); error_reporting(E_ALL); setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251'); $text='<p align="left" style="font-size:9pt;" onclock="exit();">abzaz</p>;'; $poisk='/(<p)[^<>]+>([^<>]+)(<\/p>)/si'; preg_match_all($poisk,$text,$new); echo $new[1][0]; echo ">"; echo $new[2][0]; echo $new[3][0]; ?>
PHP: <?php function tag_replace($matches){ $tag = $matches[1]; $tags = array( 'a' => array('href'), 'img' => array('src', 'alt') ); if(!isset($tags[$tag])){ return '<'.$tag.'>'; } else { preg_match_all('#\s*([a-z]*)="([^"]+)"#sUi', $matches[2], $matches); $output = '<'.$tag; for($i = 0; $i < count($matches[1]); $i++){ $attr = $matches[1][$i]; $value = $matches[2][$i]; if(in_array($attr, $tags[$tag]) && $value != ''){ $output .= ' '.$attr.'="'.$value.'"'; } } $output .= '>'; return $output; } } $text = '<p align="left" style="font-size:9pt;" onclock="exit();">abzaz</p><img bla="1" src=2 src="git.jpg"><a href="mail.ru/mails/" alt="here is the text">link</a>'; echo preg_replace_callback('#<([a-z]+)\s*([^>]*)>#si', 'tag_replace', $text); ?> this task can not be done with one regular expression. I think it's better to call function to work with tag attributes. html tag attributes should be enclosed with double quotes ", and value should not contain double quote.
Возможны баги: Код (Text): $str = preg_replace('/<([^imga]+)[^>]*>(.*?)<\/\1>/s', '<\1>\2</\1>', $str);
Не все же кавычки используют, бывает очень часто и одинарные используются: заменить на: Код (Text): preg_match_all('#\s*([a-z]*)=[\'"]([^"]+)[\'"]#sUi', $matches[2], $matches);
PHP: <?php error_reporting(-1); class MyHtmlTidy { const TAG = '<(?:"[^"]*"|\'[^\']*\'|[^\'">])*>', ATTR = '\w++\s*=\s*"[^"]++"|\w++\s*=\s*\'[^\']++\'|\w++\s*=\s*[^\s]++'; private $_goodTags = array('b', 'i', 'u', 's', 'p', 'a', 'img', 'br', 'hr'), $_selfClose = array('img', 'br', 'hr'), $_goodAttrs = array( 'a' => array('href', 'title'), 'img' => array('src', 'alt')), $_nest = array(); public $errors = array(); public function preparse($html) { $this->_nest = array(); $this->errors = array(); $text = preg_replace_callback('/('.self::TAG.')/Uus', array($this, '_replace'), $html); if (!empty($this->_nest)) { $this->errors[] = 'Unclosed tags ' . implode(', ', $this->_nest); $text .= '</' . implode('></', array_reverse($this->_nest)) . '>'; } return $text; } private function _replace($matches) { $tag = $matches[1]; preg_match('/^<\/?(\w++)/', $tag, $m); $tagName = strtolower($m[1]); $isSelfClosed = $tag{strlen($tag) - 2} == '/'; $attrs = trim(substr($tag, strlen($m[0]), ($isSelfClosed ? -2 : -1))); if (!in_array($tagName, $this->_goodTags)) { $this->errors[] = 'Tag ' . $tagName . ' is deprecated'; return ''; } // Closing tag if ($tag{1} == '/') { if (empty($this->_nest) || end($this->_nest) != $tagName) { $this->errors[] = 'Odd close tag ' . $tagName; return '<' . $tagName . '></' . $tagName . '>'; } array_pop($this->_nest); return '</' . $tagName . '>'; } // Open tag or self-closing tag $isSelfClosed = $isSelfClosed || in_array($tagName, $this->_selfClose); if (!$isSelfClosed) { $this->_nest[] = $tagName; } if (!isset($this->_goodAttrs[$tagName])) { // No attributes at all if (strlen($attrs)) { $this->errors[] = 'Tag ' . $tagName . ' cannot have attributes'; } $attrs = ''; } else { // Check every attribute preg_match_all('/'.self::ATTR.'/Uus', $attrs, $m); $attrs = $m[0]; foreach ($attrs as $i => $attr) { $p = strpos($attr, '='); $attrName = strtolower(trim(substr($attr, 0, $p))); if (!in_array($attrName, $this->_goodAttrs[$tagName])) { $this->errors[] = 'Wrong ' . $tagName . ' attribute ' . $attrName; unset($attrs[$i]); } else { $attrs[$i] = $attrName . '=' . trim(substr($attr, $p + 1)); } } $attrs = count($attrs) ? (' ' . implode(' ', $attrs)) : ''; } return '<' . $tagName . $attrs . ($isSelfClosed ? '/>' : '>'); } } $t = new MyHtmlTidy(); $html = <<<HTML <p class='blabla'>dslkldsldslsd<br> kjksdjsdk<a href="http://thesite.name/path" target="_new" title="ololo" onclick="javascript:doit('xxx')">djdkjdk</a> <img src=0.gif alt='pysh-pysh'> ds;lsd;; <b>skjskjsk kjdkjdkd HTML; header('Content-type: text/plain'); echo $html; echo "\n===========================\n"; $preparsed = $t->preparse($html); if (!empty($t->errors)) { echo implode("\n", $t->errors); echo "\n===========================\n"; } echo $preparsed;
По-моему tinymce как раз это самое и делает, чего тут невозможного? Но вот по хорошему бы хорошо будет сделать через preg_replace_callback PHP: <?php $test = '<p align="left" style="font-size:9pt;" onclock="exit();">abzaz</p><img bla="1" src=2 src="git.jpg"><a href="mail.ru/mails/" alt="here is the text">link</a>'; function callback($m) { $attr = array( 'a' => array('href', 'alt', 'style'), 'img' => array('src', 'alt', 'style'), 'p' => array('align', 'style') ); //поиск атрибутов preg_match_all('/('.implode('|', $attr[$m[1]]). ')\s*=\s*([`\'"])(.*?)\2/', $m[2], $k); return '<' . $m[1] . ' '. trim(implode(' ', $k[0])) . '>'; } echo preg_replace_callback('/<\s*([ap]|img)(.*?)>/', 'callback', $test); ?> Пропускать ли ту ошибку где src=2 без кавычек - пусть автор сам решает. И ещё - не пытайтесь автоматически исправить код высокой степени загаженности: в жизни такое встречается очень редко, так как нормальные кодеры знают как правильно писать, а обезьяны пользуются хтмл-генерилками, которые тупо не дают ничего испортить.