За последние 24 часа нас посетили 19586 программистов и 1719 роботов. Сейчас ищут 1767 программистов ...

Многим пригодится такая регулярка - помогите написать...

Тема в разделе "Регулярные выражения", создана пользователем enshtein, 14 май 2009.

  1. enshtein

    enshtein Активный пользователь

    С нами с:
    27 авг 2006
    Сообщения:
    291
    Симпатии:
    0
    Нужно написать регулярное выражение которое бы обрезало у тегов (за исключением некоторых) все свойства (атрибуты) - т.е. чтобы на выходе были просто чистые теги
    к примеру есть строка
    HTML:
    1. <p align="left" style="font-size:9pt;" onclock="exit();">абзац</p>
    а на выходе после регулярки получаем:
    HTML:
    1. <p>абзац</p>
    но необходимо некоторые теги исключать из такой обрезки к примеру теги <img src="" aling="left"><a href=""> не трогать
     
  2. Dima4321

    Dima4321 Активный пользователь

    С нами с:
    1 апр 2009
    Сообщения:
    683
    Симпатии:
    0
    Код (Text):
    1. <?php
    2.  
    3. ini_set('display_errors',1);
    4. error_reporting(E_ALL);
    5.  
    6. setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251');
    7.  
    8.  
    9. $text='<p align="left" style="font-size:9pt;" onclock="exit();">abzaz</p>;';
    10.  
    11.  
    12.  
    13. $poisk='/(<p)[^<>]+>([^<>]+)(<\/p>)/si';
    14.  
    15.  
    16. preg_match_all($poisk,$text,$new);
    17.  
    18.  
    19.  
    20.  
    21. echo $new[1][0];
    22. echo ">";
    23. echo $new[2][0];
    24. echo $new[3][0];
    25.  
    26.  
    27.   ?>
     
  3. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Лучше preg_replace('/<\s*p.*?>(.*?)<\s*\/p\s*>/', '<p>\1</p>', $s);
     
  4. Gromo

    Gromo Активный пользователь

    С нами с:
    24 май 2010
    Сообщения:
    2.786
    Симпатии:
    2
    Адрес:
    Ташкент
    PHP:
    1.  
    2. <?php
    3.  
    4. function tag_replace($matches){
    5.   $tag = $matches[1];
    6.   $tags = array(
    7.     'a' => array('href'),
    8.     'img' => array('src', 'alt')
    9.     );
    10.   if(!isset($tags[$tag])){
    11.     return '<'.$tag.'>';
    12.   } else {
    13.     preg_match_all('#\s*([a-z]*)="([^"]+)"#sUi', $matches[2], $matches);
    14.     $output = '<'.$tag;
    15.     for($i = 0; $i < count($matches[1]); $i++){
    16.       $attr = $matches[1][$i];
    17.       $value = $matches[2][$i];
    18.       if(in_array($attr, $tags[$tag]) && $value != ''){
    19.         $output .= ' '.$attr.'="'.$value.'"';
    20.       }
    21.     }
    22.     $output .= '>';
    23.     return $output;
    24.   }
    25. }
    26.  
    27.  
    28. $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>';
    29. echo preg_replace_callback('#<([a-z]+)\s*([^>]*)>#si', 'tag_replace', $text);
    30.  
    31. ?>
    32.  
    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.
     
  5. Jampire

    Jampire Активный пользователь

    С нами с:
    22 авг 2009
    Сообщения:
    181
    Симпатии:
    0
    Адрес:
    Гомель
    Возможны баги:
    Код (Text):
    1. $str = preg_replace('/<([^imga]+)[^>]*>(.*?)<\/\1>/s', '<\1>\2</\1>', $str);
     
  6. Nazorei

    Nazorei Активный пользователь

    С нами с:
    1 фев 2007
    Сообщения:
    228
    Симпатии:
    0


    Не все же кавычки используют, бывает очень часто и одинарные используются: заменить на:
    Код (Text):
    1. preg_match_all('#\s*([a-z]*)=[\'"]([^"]+)[\'"]#sUi', $matches[2], $matches);
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.119
    Симпатии:
    1.245
    Адрес:
    там-сям
    PHP:
    1. <?php
    2.  
    3.  
    4. class MyHtmlTidy
    5. {
    6.     const
    7.         TAG  = '<(?:"[^"]*"|\'[^\']*\'|[^\'">])*>',
    8.         ATTR = '\w++\s*=\s*"[^"]++"|\w++\s*=\s*\'[^\']++\'|\w++\s*=\s*[^\s]++';
    9.  
    10.     private
    11.         $_goodTags  = array('b', 'i', 'u', 's', 'p', 'a', 'img', 'br', 'hr'),
    12.         $_selfClose = array('img', 'br', 'hr'),
    13.         $_goodAttrs = array(
    14.                       'a'   => array('href', 'title'),
    15.                       'img' => array('src', 'alt')),
    16.         $_nest      = array();
    17.  
    18.     public
    19.         $errors = array();
    20.  
    21.     public function preparse($html)
    22.     {
    23.         $this->_nest = array();
    24.         $this->errors = array();
    25.         $text = preg_replace_callback('/('.self::TAG.')/Uus', array($this, '_replace'), $html);
    26.         if (!empty($this->_nest)) {
    27.             $this->errors[] = 'Unclosed tags ' . implode(', ', $this->_nest);
    28.             $text .= '</' . implode('></', array_reverse($this->_nest)) . '>';
    29.         }
    30.         return $text;
    31.     }
    32.  
    33.     private function _replace($matches)
    34.     {
    35.         $tag = $matches[1];
    36.  
    37.         preg_match('/^<\/?(\w++)/', $tag, $m);
    38.         $tagName = strtolower($m[1]);
    39.         $isSelfClosed = $tag{strlen($tag) - 2} == '/';
    40.         $attrs = trim(substr($tag, strlen($m[0]), ($isSelfClosed ? -2 : -1)));
    41.  
    42.         if (!in_array($tagName, $this->_goodTags)) {
    43.             $this->errors[] = 'Tag ' . $tagName . ' is deprecated';
    44.             return '';
    45.         }
    46.  
    47.         // Closing tag
    48.         if ($tag{1} == '/') {
    49.             if (empty($this->_nest) || end($this->_nest) != $tagName) {
    50.                 $this->errors[] = 'Odd close tag ' . $tagName;
    51.                 return '<' . $tagName . '></' . $tagName . '>';
    52.             }
    53.             array_pop($this->_nest);
    54.             return '</' . $tagName . '>';
    55.         }
    56.  
    57.         // Open tag or self-closing tag
    58.         $isSelfClosed = $isSelfClosed || in_array($tagName, $this->_selfClose);
    59.  
    60.         if (!$isSelfClosed) {
    61.             $this->_nest[] = $tagName;
    62.         }                      
    63.  
    64.         if (!isset($this->_goodAttrs[$tagName])) {
    65.             // No attributes at all
    66.             if (strlen($attrs)) {
    67.                 $this->errors[] = 'Tag ' . $tagName . ' cannot have attributes';
    68.             }
    69.             $attrs = '';
    70.         } else {
    71.             // Check every attribute
    72.             preg_match_all('/'.self::ATTR.'/Uus', $attrs, $m);
    73.             $attrs = $m[0];
    74.             foreach ($attrs as $i => $attr) {
    75.                 $p = strpos($attr, '=');
    76.                 $attrName = strtolower(trim(substr($attr, 0, $p)));
    77.                 if (!in_array($attrName, $this->_goodAttrs[$tagName])) {
    78.                     $this->errors[] = 'Wrong ' . $tagName . ' attribute ' . $attrName;
    79.                     unset($attrs[$i]);
    80.                 } else {
    81.                     $attrs[$i] = $attrName . '=' . trim(substr($attr, $p + 1));
    82.                 }
    83.             }
    84.             $attrs = count($attrs) ? (' ' . implode(' ', $attrs)) : '';
    85.         }
    86.    
    87.         return '<' . $tagName . $attrs . ($isSelfClosed ? '/>' : '>');
    88.     }
    89. }
    90.  
    91. $t = new MyHtmlTidy();
    92.  
    93. $html = <<<HTML
    94. <p class='blabla'>dslkldsldslsd<br>
    95. kjksdjsdk<a href="http://thesite.name/path" target="_new" title="ololo" onclick="javascript:doit('xxx')">djdkjdk</a>
    96. <img src=0.gif alt='pysh-pysh'>
    97. ds;lsd;; <b>skjskjsk kjdkjdkd
    98. HTML;
    99.  
    100. header('Content-type: text/plain');
    101.  
    102. echo $html;
    103. echo "\n===========================\n";
    104.  
    105. $preparsed = $t->preparse($html);
    106. if (!empty($t->errors)) {
    107.     echo implode("\n", $t->errors);
    108.     echo "\n===========================\n";
    109. }
    110. echo $preparsed;
    111.  
     
  8. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    По-моему tinymce как раз это самое и делает, чего тут невозможного?:)

    Но вот по хорошему бы хорошо будет сделать через preg_replace_callback

    PHP:
    1. <?php
    2. $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>';
    3.  
    4. function callback($m)
    5. {
    6.   $attr = array(
    7.     'a' => array('href', 'alt', 'style'),
    8.     'img' => array('src', 'alt', 'style'),
    9.     'p' => array('align', 'style')
    10.   );
    11.   //поиск атрибутов
    12.   preg_match_all('/('.implode('|', $attr[$m[1]]).
    13.   ')\s*=\s*([`\'"])(.*?)\2/', $m[2], $k);
    14.   return '<' . $m[1] . ' '. trim(implode(' ', $k[0])) . '>';
    15. }
    16.  
    17. echo preg_replace_callback('/<\s*([ap]|img)(.*?)>/', 'callback', $test);
    18. ?>
    Пропускать ли ту ошибку где src=2 без кавычек - пусть автор сам решает.


    И ещё - не пытайтесь автоматически исправить код высокой степени загаженности: в жизни такое встречается очень редко, так как нормальные кодеры знают как правильно писать, а обезьяны пользуются хтмл-генерилками, которые тупо не дают ничего испортить.