За последние 24 часа нас посетили 18153 программиста и 1625 роботов. Сейчас ищут 1316 программистов ...

Замена с исключением

Тема в разделе "Регулярные выражения", создана пользователем Freakmeister, 16 окт 2012.

  1. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Реально ли составить регулярку, чтобы в тексте все \n заменялись на <br>, но только не внутри тега
    HTML:
    1.  
    ? У меня в новостях реализован автоматический перенос строки, а недавно я стал использовать бб-тег
    HTML:
    1.  и внутри него проявляются косяки - например, весь html-код приходится писать в одну строку, иначе в коде появляется лишний <br>.
     
  2. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Реально. Инфа 100%.
     
  3. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Спасибо за желчь.

    Пробовал заменить \n внутри тега
    HTML:
    1.  
    на временную строчку: lRkN5a1Bk0QHC32hWWsp - почти сработало. Но моя регулярка заменяет только первый попавшийся \n, а не все. Как сделать чтобы заменяла все - я не знаю.

    Код (PHP):
    1. <?php
    2. $text = preg_replace("'\[html\](.*?)\n(.*?)\[\/h tml\]'is", "\[html\]\\1lRkN5a1Bk0QHC32hWWsp\\2\[\/html\] ", $text);
    3. $text = str_ireplace("\n", "<*br>", $text); //без * - форум глючит
    4. $text = str_replace("lRkN5a1Bk0QHC32hWWsp", "\n", $text);
    5. ?>
     
  4. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я не шарю в регулярках. То есть совсем. Но я точно знаю, что можно. =) Эта регулярка ничем не будет отличаться от других регулярок.
     
  5. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Код (PHP):
    1. <?php
    2. $in = 'Текст
    3. Текст
    4. Текст
    5. [html]Текст
    6. Текст
    7. Текст[/html]
    8. Текст
    9. Текст';
    10. if(($start = strpos($in, '[html]')) !== false and ($end = strpos($in, '[/html]')) !== false and $start < $end) {
    11.     $out = nl2br(substr($in, 0, $start)) . substr($in, $start, $end + 7 - $start) . nl2br(substr($in, $end + 7));
    12. } else {
    13.     $out = nl2br($in);
    14. }
    15. echo($out);
    16. ?>
     
  6. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Код (PHP):
    1. $in = 'Текст1
    2. Текст2
    3. Текст3
    4. [html]Текст4
    5. Текст5
    6. Текст6[/html]
    7. Текст7
    8. Текст8';
    9. echo preg_replace('#((?<=\[\/html\]).+|.+(?=\[html\]))#isue',"nl2br('\\1')",$in); 
    или аналогично но через preg_replace_callback()
     
  7. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    sobachnik, ты взорвал мне мозг и поломал жизнь.) Каааак оно работает? Откуда взялись переменные $start и $end?
     
  8. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Код (PHP):
    1. $start = strpos($in, '[html]')
    2.  
    не оно? )
     
  9. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Я сначала прочитал == вместо =, ну вы поняли.)) Оно работает идеально, но только если
    HTML:
    1.  
    в тексте встречается всего раз.

    runcore, в твоей регулярке была ошибка:
    Код (PHP):
    1. preg_replace('#((?<=\[\/html\]).+|.+(?=\[html\]))#isue',nl2br("'\\1'"),$in); 
    А результат тот же самый - срабатывает всего для одного тега
    HTML:
    1.  
    . =(
     
  10. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Заговнокодил костыль. Вроде работает.

    Код (PHP):
    1. $ar = explode('html]', $in);
    2.     $new = null;
    3.     foreach($ar as $a){ 
    4.         if(substr($a, strlen($a)-2) != '[/') { $a = nl2br($a); }
    5.         $new .= $a.'html]';
    6.     }
    7.     $out = substr($new, 0, strlen($new)-5);
    8.     return $out; 
     
  11. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    я показал направление решения. надо было просто додумать под себя и попробовать через preg_replace_callback() как я там и написал.

    Код (PHP):
    1.  '#(?<=\[\/html\]|^).+?(?=\[html\]|$)#isu'
    2.  ,create_function('$m','return nl2br($m[0]);')
    3.  ,$in
    4. ); 
     
  12. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Я не шарю в регулярках, поэтому пишу костыли. =\
    Последняя регулярка не обрабатывает первый тэг
    HTML:
    1.  
    , если с него начинается текст.
     
  13. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    '#(?<=\[\/html\]|^)[^\[]+?(?=\[html\]|$)#isu'
     
  14. Freakmeister

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

    С нами с:
    20 дек 2009
    Сообщения:
    888
    Симпатии:
    5
    Теперь конфликт с другими бб-кодами. =) Если сделать так, то nl2br внутри тега b не срабатывает:

    Код (PHP):
    1. $in = '[b]asdasdsad
    2. asdasdasd
    3. <div class="test"></div>
    4. <div class="test"></div>
    5. asdasd
    6. asdasd[/b]
    7.  
    8. [html]html<div class="test"></div>
    9. <div class="test"></div>
    10. html[/html]'; 
     
  15. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    "'\
    HTML:
    1. (.*?)\
    'si"