PHP: лучший способ извлечь текст в скобках?


каков наилучший / наиболее эффективный способ извлечения набора текста между скобками? Скажем, я хотел получить строку " текст "из строки" игнорировать все, кроме этого (текста) " самым эффективным способом.

пока лучшее, что я придумал это:

$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);

$shortString = substr($fullString, $start, $end);

есть ли лучший способ сделать это? Я знаю, что в целом использование регулярных выражений имеет тенденцию быть менее эффективным, но если я не могу уменьшить количество вызовов функций, возможно, это был бы лучший подход? Мысли?

5 58

5 ответов:

Я бы просто сделал регулярное выражение и покончил с этим. если вы не делаете достаточно итераций, что это становится огромной проблемой производительности, это просто легче кодировать (и понять, когда вы оглядываетесь на него)

$text = 'ignore everything except this (text)';
preg_match('#\((.*?)\)#', $text, $match);
print $match[1];

Итак, на самом деле, код, который вы опубликовали, не работает: substr()'s параметры $string, $start и $ length и strpos()'s параметры $haystack,$needle. Немного изменено:

$str = "ignore everything except this (text)";
$start  = strpos($str, '(');
$end    = strpos($str, ')', $start + 1);
$length = $end - $start;
$result = substr($str, $start + 1, $length - 1);

некоторые тонкости: я использовал $start + 1 в параметре offset, чтобы помочь PHP при выполнении strpos() поиск по второй скобке; мы увеличиваем $start одна и уменьшить $length чтобы исключить скобки из матча.

кроме того, нет ошибки проверка в этом коде: вы хотите, чтобы убедиться, что $start и $end не = = = false перед выполнением substr.

как использовать strpos/substr по сравнению с регулярным выражением; с точки зрения производительности, этот код будет бить регулярное выражение руки вниз. Хотя это немного более многословно. Я ем и дышу strpos/substr, так что я не возражаю против этого слишком много, а кто-то другой может предпочесть компактность в regex.

использовать регулярное выражение:

if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
    $text = $match[1];

Это пример кода для извлечения всего текста между ' ['и'] ' и хранения его 2 отдельных массива (т. е. текст внутри скобок в одном массиве и текст вне скобок в другом массиве)

   function extract_text($string)
   {
    $text_outside=array();
    $text_inside=array();
    $t="";
    for($i=0;$i<strlen($string);$i++)
    {
        if($string[$i]=='[')
        {
            $text_outside[]=$t;
            $t="";
            $t1="";
            $i++;
            while($string[$i]!=']')
            {
                $t1.=$string[$i];
                $i++;
            }
            $text_inside[] = $t1;

        }
        else {
            if($string[$i]!=']')
            $t.=$string[$i];
            else {
                continue;
            }

        }
    }
    if($t!="")
    $text_outside[]=$t;

    var_dump($text_outside);
    echo "\n\n";
    var_dump($text_inside);
  }

выход: extract_text ("привет, как дела?"); произведет:

array(1) {
  [0]=>
  string(18) "hello how are you?"
}

array(0) {
}

extract_text ("привет [http://www.google.com/test.mp3 - как поживаешь?"); будет производить

array(2) {
  [0]=>
  string(6) "hello "
  [1]=>
  string(13) " how are you?"
}


array(1) {
  [0]=>
  string(30) "http://www.google.com/test.mp3"
}

эта функция может быть полезна.

    public static function getStringBetween($str,$from,$to, $withFromAndTo = false)
    {
       $sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
       if ($withFromAndTo)
         return $from . substr($sub,0, strrpos($sub,$to)) . $to;
       else
         return substr($sub,0, strrpos($sub,$to));
    }
    $inputString = "ignore everything except this (text)";
    $outputString = getStringBetween($inputString, '(', ')'));
    echo $outputString; 
    //output will be test

    $outputString = getStringBetween($inputString, '(', ')', true));
    echo $outputString; 
    //output will be (test)

strpos() => который используется для поиска позиции первого появления в строке.

strrpos() => который используется для поиска позиции первого появления в строке.