【问题标题】:Get string between - Find all occurrences PHP获取之间的字符串 - 查找所有出现的 PHP
【发布时间】:2015-01-20 14:18:49
【问题描述】:

I found this function 在两个文本字符串、html 或其他字符串之间查找数据。

如何更改它以便找到所有出现的事件?每次出现 $start [some-random-data] $end 之间的每个数据。我想要文档的所有 [一些随机数据](它总是不同的数据)。

function getStringBetween($string, $start, $end) {
    $string = " ".$string;
    $ini = strpos($string,$start);
    if ($ini == 0) return "";
    $ini += strlen($start);
    $len = strpos($string,$end,$ini) - $ini;
    return substr($string,$ini,$len);
}

【问题讨论】:

  • 您需要文档的数据(字符串)计数器吗??
  • 要捕获更多内容,您需要继续使用正则表达式。见preg_match_all
  • 我查看了 preg_match_all,但我不知道如何制作正则表达式。
  • Rajib - 我不明白你的意思?我希望该函数返回一个出现次数的数组。
  • 如果数据看起来像STARTfooSTARTbarENDbazEND,你想让函数做什么?

标签: php


【解决方案1】:

一种可能的方法:

function getContents($str, $startDelimiter, $endDelimiter) {
  $contents = array();
  $startDelimiterLength = strlen($startDelimiter);
  $endDelimiterLength = strlen($endDelimiter);
  $startFrom = $contentStart = $contentEnd = 0;
  while (false !== ($contentStart = strpos($str, $startDelimiter, $startFrom))) {
    $contentStart += $startDelimiterLength;
    $contentEnd = strpos($str, $endDelimiter, $contentStart);
    if (false === $contentEnd) {
      break;
    }
    $contents[] = substr($str, $contentStart, $contentEnd - $contentStart);
    $startFrom = $contentEnd + $endDelimiterLength;
  }

  return $contents;
}

用法:

$sample = '<start>One<end>aaa<start>TwoTwo<end>Three<start>Four<end><start>Five<end>';
print_r( getContents($sample, '<start>', '<end>') );
/*
Array
(
    [0] => One
    [1] => TwoTwo
    [2] => Four
    [3] => Five
)
*/ 

Demo.

【讨论】:

  • 有人可以向我解释一下使用什么搜索算法来实现这个吗?有人可以用文字向我解释一下这个函数究竟是做什么的吗?
  • 这就像您编写它的方式一样完美无缺。太感谢了!它发现每一个事件。例如,如果您要查找两个 html 标记之间的文本,请将 html 页面作为字符串获取。然后将 $startDelimiter 设置为第一个标签,将 $endDelimiter 设置为第二个标签。该函数将返回数组中两个标签之间的每个实例。
  • @Erdss4 在每次迭代中,循环首先收集 $startDelimiter 的新位置,然后收集 $endDelimiter 的位置。查找总是从前一个循环留下的位置开始。这是一般描述,有关详细信息,请询问具体的更多问题。 )
  • 这个答案缺少教育解释。
【解决方案2】:

您可以使用正则表达式来做到这一点:

function getStringsBetween($string, $start, $end)
{
    $pattern = sprintf(
        '/%s(.*?)%s/',
        preg_quote($start),
        preg_quote($end)
    );
    preg_match_all($pattern, $string, $matches);

    return $matches[1];
}

【讨论】:

  • 这对标准字符串有好处,但对于使用美元符号和胡萝卜作为分隔符之类的东西却很糟糕,因为它会弄乱正则表达式
  • 由于某种原因,preg_match_allpreg_match_all 不适用于大字符串,我试图从表中获取所有 。
【解决方案3】:

我喜欢使用explode 来获取两个字符串之间的字符串。此函数也适用于多次出现。

function GetIn($str,$start,$end){
    $p1 = explode($start,$str);
    for($i=1;$i<count($p1);$i++){
        $p2 = explode($end,$p1[$i]);
        $p[] = $p2[0];
    }
    return $p;
}

【讨论】:

    【解决方案4】:

    我需要在特定的第一个和最后一个标签之间找到所有这些出现并以某种方式更改它们并取回更改的字符串。

    所以我在函数之后添加了这个小代码到raina77ow方法中。

            $sample = '<start>One<end> aaa <start>TwoTwo<end> Three <start>Four<end> aaaaa <start>Five<end>';
            $sample_temp = getContents($sample, '<start>', '<end>');
            $i = 1;
            foreach($sample_temp as $value) {
                $value2 = $value.'-'.$i; //there you can change the variable
                $sample=str_replace('<start>'.$value.'<end>',$value2,$sample);
                $i = ++$i;
            }
            echo $sample;
    

    现在输出样本已经删除了标签,并且它们之间的所有字符串都添加了这样的数字:

    One-1 aaa TwoTwo-2 三 四-3 aaaaa 五-4

    但是您可以对它们做任何其他事情。也许对某人有帮助。

    【讨论】:

      【解决方案5】:

      这里有一些很好的解决方案,但是对于从 HTML 中提取部分代码并不完美,这是我现在的问题,因为我需要在压缩 HTML 之前从 HTML 中获取脚本块。所以在@raina77ow 原始解决方案的基础上,由@Cas Tuyn 扩展,我得到了这个:

      $test_strings = [
          '0<p>a</p>1<p>b</p>2<p>c</p>3',
          '0<p>a</p>1<p>b</p>2<p>c</p>',
          '<p>a</p>1<p>b</p>2<p>c</p>3',
          '<p>a</p>1<p>b</p>2<p>c</p>',
          '<p></p>1<p>b'
      ];
      
      /**
      * Seperate a block of code by sub blocks. Example, removing all <script>...<script> tags from HTML kode
      * 
      * @param string $str, text block
      * @param string $startDelimiter, string to match for start of block to be extracted
      * @param string $endDelimiter, string to match for ending the block to be extracted
      * @return array [all full blocks, whats left of string]
      */
      function getDelimitedStrings($str, $startDelimiter, $endDelimiter) {
          $contents = array();
          $startDelimiterLength = strlen($startDelimiter);
          $endDelimiterLength = strlen($endDelimiter);
          $startFrom = $contentStart = $contentEnd = $outStart = $outEnd = 0;
          while (false !== ($contentStart = strpos($str, $startDelimiter, $startFrom))) {
              $contentStart += $startDelimiterLength;
              $contentEnd = strpos($str, $endDelimiter, $contentStart);
              $outEnd = $contentStart - 1;
              if (false === $contentEnd) {
                  break;
              }
              $contents['in'][] = substr($str, ($contentStart-$startDelimiterLength), ($contentEnd + ($startDelimiterLength*2) +1) - $contentStart);
              if( $outStart ){
                  $contents['out'][] = substr($str, ($outStart+$startDelimiterLength+1), $outEnd - $outStart - ($startDelimiterLength*2));
              } else if( ($outEnd - $outStart - ($startDelimiterLength-1)) > 0 ){
                  $contents['out'][] = substr($str, $outStart, $outEnd - $outStart - ($startDelimiterLength-1));
              }
              $startFrom = $contentEnd + $endDelimiterLength;
              $startFrom = $contentEnd;
              $outStart = $startFrom;
          }
          $total_length = strlen($str);
          $current_position = $outStart + $startDelimiterLength + 1;
          if( $current_position < $total_length )
              $contents['out'][] = substr($str, $current_position);
      
          return $contents;
      }
      
      foreach($test_strings AS $string){
          var_dump( getDelimitedStrings($string, '<p>', '</p>') );
      }
      

      这将提取所有

      wlements 与可能的 innerHTML 以及,给出以下结果:

      array (size=2)
      'in' => array (size=3)
          0 => string '<p>a</p>' (length=8)
          1 => string '<p>b</p>' (length=8)
          2 => string '<p>c</p>' (length=8)
      'out' => array (size=4)
          0 => string '0' (length=1)
          1 => string '1' (length=1)
          2 => string '2' (length=1)
          3 => string '3' (length=1)
      
      array (size=2)
      'in' => array (size=3)
          0 => string '<p>a</p>' (length=8)
          1 => string '<p>b</p>' (length=8)
          2 => string '<p>c</p>' (length=8)
      'out' => array (size=3)
          0 => string '0' (length=1)
          1 => string '1' (length=1)
          2 => string '2' (length=1)
      
      array (size=2)
      'in' => array (size=3)
          0 => string '<p>a</p>' (length=8)
          1 => string '<p>b</p>' (length=8)
          2 => string '<p>c</p>' (length=8)
      'out' => array (size=3)
          0 => string '1' (length=1)
          1 => string '2' (length=1)
          2 => string '3' (length=1)
      
      array (size=2)
      'in' => array (size=3)
          0 => string '<p>a</p>' (length=8)
          1 => string '<p>b</p>' (length=8)
          2 => string '<p>c</p>' (length=8)
      'out' => array (size=2)
          0 => string '1' (length=1)
          1 => string '2' (length=1)
      
      array (size=2)
      'in' => array (size=1)
          0 => string '<p></p>' (length=7)
      'out' => array (size=1)
          0 => string '1<p>b' (length=5)
      

      您可以在此处查看演示:3v4l.org/TQLmn

      【讨论】:

        【解决方案6】:

        我还需要模式之外的文本。所以我把上面的raina77ow的答案改了一点:

        function get_delimited_strings($str, $startDelimiter, $endDelimiter) {
            $contents = array();
            $startDelimiterLength = strlen($startDelimiter);
            $endDelimiterLength = strlen($endDelimiter);
            $startFrom = $contentStart = $contentEnd = $outStart = $outEnd = 0;
            while (false !== ($contentStart = strpos($str, $startDelimiter, $startFrom))) {
                $contentStart += $startDelimiterLength;
                $contentEnd = strpos($str, $endDelimiter, $contentStart);
                $outEnd = $contentStart - 1;
                if (false === $contentEnd) {
                    break;
                }
                $contents['in'][] = substr($str, $contentStart, $contentEnd - $contentStart);
                $contents['out'][] = substr($str, $outStart, $outEnd - $outStart);
                $startFrom = $contentEnd + $endDelimiterLength;
                $outStart = $startFrom;
            }
            $contents['out'][] = substr($str, $outStart, $contentEnd - $outStart);
            return $contents;
        }
        

        用法:

            $str = "Bore layer thickness [2 mm] instead of [1,25 mm] with [0,1 mm] deviation.";
            $cas = get_delimited_strings($str, "[", "]");
        

        给予:

        array(2) { 
            ["in"]=> array(3) { 
                [0]=> string(4) "2 mm" 
                [1]=> string(7) "1,25 mm" 
                [2]=> string(6) "0,1 mm" 
            } 
            ["out"]=> array(4) { 
                [0]=> string(21) "Bore layer thickness " 
                [1]=> string(12) " instead of " 
                [2]=> string(6) " with " 
                [3]=> string(10) " deviation" 
            } 
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-22
          • 2016-03-18
          • 1970-01-01
          • 1970-01-01
          • 2023-02-25
          • 2012-10-12
          • 1970-01-01
          相关资源
          最近更新 更多