Как я могу заменить строки НЕ в теге ссылки? - PullRequest
3 голосов
/ 30 января 2010

Я работаю над этой функцией PHP. Идея состоит в том, чтобы заключить определенные слова, встречающиеся в строке, в определенные теги (как слова, так и теги, заданные в массиве). Это работает хорошо !, но когда эти слова встречаются в связанном тексте или его атрибуте 'src', тогда, конечно, ссылка не работает и наполняется тегами, или генерируются теги, которые не должны быть внутри ссылки. Вот что у меня сейчас:

function replace() {
  $terminos = array (
  "beneficios" => "h3",
  "valoracion" => "h2",
  "empresarios" => "h2",
  "tecnologias" => "h2",
  "...and so on..." => "etc",
  );

  foreach ($terminos as $key => $value)
  {
  $body = "string where the word empresarios should be replaced; but the word <a href='http://www.empresarios.com'>empresarios</a> should not be replaced inside <a> tags nor in the URL of their 'src' attribute.";
  $tagged = "<".$value.">".$key."</".$value.">";
  $result = str_replace($key, $tagged, $body);
  }
}

Функция в этом примере должна вернуть "string where the word <h2>empresarios</h2> should be replaced; but the word <a href='http://www.empresarios.com'>empresarios</a> should not be replaced inside <a> tags nor in the URL of their 'src' attribute."

Мне бы хотелось, чтобы эта функция замещения работала по всей строке, но не внутри тегов и в ее атрибутах!

(Я хотел бы сделать то, что упомянуто в следующем потоке, просто мне нужно не в javascript, а в PHP: /questions/1666790/how-to-replace-text-not-within-a-specific-tag-in-javascript)

Ответы [ 2 ]

3 голосов
/ 30 января 2010

Используйте DOM и изменяйте только текстовые узлы:

$s = "foo <a href='http://test.com'>foo</a> lorem bar ipsum foo. <a>bar</a> not a test";
echo htmlentities($s) . '<hr>';

$d = new DOMDocument;
$d->loadHTML($s);

$x = new DOMXPath($d);
$t = $x->evaluate("//text()");

$wrap = array(
    'foo' => 'h1',
    'bar' => 'h2'
);

$preg_find = '/\b(' . implode('|', array_keys($wrap)) . ')\b/';

foreach($t as $textNode) {
    if( $textNode->parentNode->tagName == "a" ) {
        continue;
    }

    $sections = preg_split( $preg_find, $textNode->nodeValue, null, PREG_SPLIT_DELIM_CAPTURE);

    $parentNode = $textNode->parentNode;

    foreach($sections as $section) {  
        if( !isset($wrap[$section]) ) {
            $parentNode->insertBefore( $d->createTextNode($section), $textNode );
            continue;
        }

        $tagName = $wrap[$section];
        $parentNode->insertBefore( $d->createElement( $tagName, $section ), $textNode );
    }

    $parentNode->removeChild( $textNode );
}

echo htmlentities($d->saveHTML());

Отредактировано для замены DOMText на DOMText и DOMElement при необходимости.

0 голосов
/ 30 января 2010

На ответ, который вы указали, в JS это в основном то же самое. Вам просто нужно указать, что это строка.

$regexp = "/(<pre>(?:[^<](?!\/pre))*<\/pre>)|(\:\-\))/gi";

Также обратите внимание, что вам может понадобиться другая функция preg_replace, чтобы заменить слово «empresarios» в случае, если оно написано заглавными буквами (Empresarios) или как-то странно (EmPreSAriOS).

Также позаботьтесь о своем HTML. <h2> являются блочными элементами и могут интерпретироваться следующим образом:

строка где слово empresarios следует заменить;

и заменен

строка где слово

Empresarios

следует заменить;

Может быть, вам понадобится тег <big>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...