Найти все, что не находится между конкретными тегами - PullRequest
0 голосов
/ 18 марта 2010

Я использую

preg_match_all('/<?(.*)?>/', $bigString, $matches, PREG_OFFSET_CAPTURE);

, чтобы найти содержимое всего между <? и ?>

Теперь я хотел бы найти все, что НЕ находится между <? и ?>

Я пытаюсь использовать

preg_match_all('/^(<?(.*)?>)/', $bigString, $nonmatches, PREG_OFFSET_CAPTURE);

, но, похоже, это не работает ...

Ответы [ 2 ]

0 голосов
/ 18 марта 2010

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

Вот функция в качестве примера:

<?php

function match_all_except ($pattern, $string)
{
    preg_match_all($pattern, $string, $match, PREG_OFFSET_CAPTURE);

    $parts = array();
    $pos = 0;

    foreach ($match[0] as $info)
    {
        $parts[] = substr($string, $pos, $info[1] - $pos);
        $pos = $info[1] + strlen($info[0]);
    }

    $parts[] = substr($string, $pos);

    return $parts;
}

$string = 'one<? foo ?>two<? bar ?>three';
$parts = match_all_except('/<\?.*?\?>/s', $string);

// Will output "one, two, three, "
foreach ($parts as $outside)
{
    echo "$outside, ";
}

?>

В качестве альтернативы, вы можете использовать это регулярное выражение /\G(?=.)((?:(?!<\?).)*)(?:<\?((?!\?>).)*(\?>|$)|$)/s в preg_match_all, чтобы захватить все части вне тегов в одну подматрицу. Хотя это может иметь свои собственные трудности, если теги не совпадают в документе равномерно.

Например,

<?php

$string = 'one<? foo ?>two<? bar ?>three';
preg_match_all('/\G(?=.)((?:(?!<\?).)*)(?:<\?((?!\?>).)*(\?>|$)|$)/s', $string, $match);

// Will output "one, two, three, "
foreach ($match[1] as $outside)
{
    echo "$outside, ";
}

?>
0 голосов
/ 18 марта 2010

подход без регулярных выражений

$str=<<<EOF
1 some words
1 some more words
<?
blah blah
blah blah
?>
2 some words
2 some words <?
jdf
sdf ?>
asdf
sdfs
EOF;

$s = explode('?>',$str);
foreach($s as $v){
  $m = strpos($v,'<?');
  if($m!==FALSE){
     print substr($v,0,$m)."\n";
  }
}
print end($s);

выход

$ php test.php
1 some words
1 some more words


2 some words
2 some words

asdf
sdfs
...