33

$stringで$char1と$ char2function delete_all_between($char1, $char2, $string) を検索し、見つかった場合は、$char1と$char2自体を含むこれら2つの文字の間のサブ文字列から$stringをクリアすることに興味があります。

例:

$string = 'Some valid and <script>some invalid</script> text!';
delete_all_between('<script>', '</script>', $string);

これで、$stringには

'Some valid and  text'; //note two spaces between 'and  text'

誰かが迅速な解決策を持っていますか?

4

8 に答える 8

62
<?php

$string = 'Some valid and <script>some invalid</script> text!';
$out = delete_all_between('<script>', '</script>', $string);
print($out);

function delete_all_between($beginning, $end, $string) {
  $beginningPos = strpos($string, $beginning);
  $endPos = strpos($string, $end);
  if ($beginningPos === false || $endPos === false) {
    return $string;
  }

  $textToDelete = substr($string, $beginningPos, ($endPos + strlen($end)) - $beginningPos);

  return delete_all_between($beginning, $end, str_replace($textToDelete, '', $string)); // recursion to ensure all occurrences are replaced
}
于 2012-10-23T13:28:52.040 に答える
48

これがワンライナーです:

preg_replace('/START[\s\S]+?END/', '', $string);

置き換えSTARTEND:)クレジットは別のSOスレッドに送られます!

于 2015-12-10T09:50:40.617 に答える
1

substr()動作が遅すぎると思います。最良の方法は次のとおりです。

return substr($string, 0, $beginningPos) . 
       substr($string, $endPos + strlen($end));
于 2013-06-17T15:44:04.320 に答える
1

実際、TWIGテンプレートのすべての変数を取得するためのシンプルで安定したソリューションを提供する関数を探していました。提案された正規表現は多くの理由でうまく機能しなかったので、タグを数えるのではなく、タグ間のすべてのコンテンツを消去することにしました^_^。

/**
     * deletes ALL the string contents between all the designated characters
     * @param $start - pattern start 
     * @param $end   - pattern end
     * @param $string - input string, 
     * @return mixed - string
     */
    function auxDeleteAllBetween($start, $end, $string) {
        // it helps to assembte comma dilimited strings
        $string = strtr($start. $string . $end, array($start => ','.$start, $end => chr(2)));
        $startPos  = 0;
        $endPos = strlen($string);
        while( $startPos !== false && $endPos !== false){
            $startPos = strpos($string, $start);
            $endPos = strpos($string, $end);
            if ($startPos === false || $endPos === false) {
                $run = false;
                return $string;
            }
            $textToDelete = substr($string, $startPos, ($endPos + strlen($end)) - $startPos);
            $string = str_replace($textToDelete, '', $string);
        }
        return $string;
    }

    /**
     * This function is intended to replace
     * //preg_match_all('/\{\%\s*([^\%\}]*)\s*\%\}|\{\{\s*([^\}\}]*)\s*\}\}/i', $this->_tplSubj, $matchesSubj);
     * which did not give intended results for some reason.
     *
     * @param $inputTpl
     * @return array
     */
    private function auxGetAllTags($inputTpl){
        $inputTpl = strtr($inputTpl, array('}}' => ','.chr(1), '{{' => chr(2)));
        return explode(',',$this->auxDeleteAllBetween(chr(1),chr(2),$inputTpl));
    }


$template = '<style>
td{border-bottom:1px solid #eee;}</style>
<p>Dear {{jedi}},<br>New {{padawan}} is waiting for your approval: </p>
<table border="0">
<tbody><tr><td><strong>Register as</strong></td><td>{{register_as}}, user-{{level}}</td></tr>
<tr><td><strong>Name</strong></td><td>{{first_name}} {{last_name}}</td></tr>...';

print_r($this->auxGetAllTags($template));
于 2016-05-23T00:02:53.650 に答える
1

私の場合、最初のバージョンに問題があります。これは私の修正バージョンです($end文字列が$beginning文字列の前にも表示される場合)

<?php 
$string = 'Some </script> valid and <script>some invalid</script> text!';
$out = delete_all_between('<script>', '</script>', $string);
print($out);

function delete_all_between($beginning, $end, $string) {
    $beginningPos = strpos($string, $beginning);
    $tmpstring = substr($string, $beginningPos);  
    $endPos = strpos($tmpstring, $end);
    if ($beginningPos === false || $endPos === false) {
        return $string;
    }
    $textToDelete = substr($string, $beginningPos, ($endPos + strlen($end)) );
    return delete_all_between($beginning, $end, str_replace($textToDelete, '', $string)); // recursion to ensure all occurrences are replaced
}
于 2021-07-23T16:13:41.830 に答える
0

htmlをDOMDocumentに解析する前に未使用のタグを削除したいので、phpでタグを削除したいと思います。

これが私が使用したコードです。最初のケースでは、カーソルは0です。これは、プログラムで再帰的に使用されるだけです。

function delete_all_betweenV2($cursor, $beginning, $end, $string, $retainSelf) {
    echo '>>>> Start '.'<br>';
    $beginningPos = strpos($string, $beginning, $cursor);
    $endPos = strpos($string, $end, $beginningPos);
    
    if ($beginningPos === false || $endPos === false) {
      echo '>>>> End '.'<br>';
      return $string;
    }    
    
    if($endPos >= strlen($string)) {
      echo '>>>> End '.'<br>';
      return $string;
    }
    
    $lenOfBeginning = strlen($beginning);
    $lenOfEnd = strlen($end);
    
    $result = $string;
    if($retainSelf) {
      echo 'b4 input String: '.$string.'<br>';
      echo 'b4 cursor = : '.$cursor. '<br>';
      echo 'b4 string: '.$string. '<br>';
      echo 'b4 beginning Pos: '.$beginningPos.'<br>';
      echo 'b4 end Pos: '.$endPos.'<br>';
      echo 'b4 length to be cut is: '.(($endPos - $lenOfEnd) - $beginningPos).'<br>';
      
      if($cursor > 0) {
        echo 'cursor is greater than 0'.'<br>';
        $textToDelete = substr($string, $beginningPos + $lenOfBeginning, ($endPos - $lenOfEnd) - $beginningPos);
      } else {
        echo 'cursor is NOT greater than 0'.'<br>';
        $textToDelete = substr($string, $beginningPos + $lenOfBeginning, ($endPos - $lenOfEnd) - $beginningPos);
      }
      
      echo 'TextToDelete:'.$textToDelete.'<br>';
        
      //$stringStart = substr($string, 0, $beginningPos + $lenOfBeginning);
      //echo $stringStart.'<br>';
      //$stringTail = substr($string, $endPos, strlen($string));
      //echo $stringTail.'<br>';    
      $result = str_replace($textToDelete, '', $string);
      $cursor = $beginningPos + $lenOfBeginning; // just make sure that the cursor search next character/word
      echo 'After cursor = : '.$cursor. '<br>';
      echo 'After result: '.$result. '<br>';
      echo 'After len of result: '.strlen($result). '<br>';
    } else {
        //$stringStart = substr($string, 0, $beginningPos);
        //echo $stringStart.'<br>';
        //$stringTail = substr($string, $endPos + $lenOfEnd, strlen($string));
        //echo $stringTail.'<br>';
        $cursor = 0;
        
        $textToDelete = substr($string, $beginningPos, ($endPos + $lenOfEnd) - $beginningPos);
        echo 'TextToDelete:'.$textToDelete.'<br>';
        $result = str_replace($textToDelete, '', $string);
    } 
    echo '>>>> End '.'<br>';
    return delete_all_betweenV2($cursor, $beginning, $end, $result, $retainSelf);
}
于 2021-05-08T08:17:12.670 に答える
0

AndreaTSのdelete_all_between()のリビジョンとして、ただしタグ属性(eg <script type='abc'>)を処理し、大文字と小文字を区別しないようにするために、これがあります...

    function delete_all_between(string $html, string $tag) {
        $startTag="<$tag ";
        $endTag="</$tag>";
        $html     =str_ireplace("<$tag>", "<$tag >", $html);
        $startPos = stripos($html, $startTag);
        $tmpStr = substr($html, $startPos);
        $endPos = stripos($tmpStr, $endTag);
        if ($startPos === false || $endPos === false) {
            return $html;
        }
        $textToDelete = substr($html, $startPos, ($endPos + strlen($startTag))+1 );
        return delete_all_between(str_replace($textToDelete, '', $html), $tag); // recursion to ensure all occurrences are replaced
    }

これを実行するphpサンドボックスについては、http://sandbox.onlinephpfunctions.com/code/1b984b61cfd1c9cea4c6eef1d765ff387a4cd9e9を参照してください。

于 2021-10-13T13:08:59.983 に答える
-2

double str_replace()を使用できます $q = str_replace('<script>', '', $string); $p = str_replace('some invalid', '', $q); echo $p;

于 2018-01-04T11:41:19.453 に答える