Какой лучший / самый эффективный способ извлечь текст, заключенный в круглые скобки? Скажем, я хотел получить строку «текст» из строки «игнорировать все, кроме этого (текста)» наиболее эффективным способом.
Пока что лучшее, что я придумал, это следующее:
$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);
$shortString = substr($fullString, $start, $end);
Есть лучший способ сделать это? Я знаю, что в целом использование регулярных выражений имеет тенденцию быть менее эффективным, но, если я не могу уменьшить количество вызовов функций, возможно, это будет лучший подход? Мысли?
s($fullString)->between("(", ")")
полезные сведения, найденные в этой автономной библиотеке .Ответы:
Я бы просто сделал регулярное выражение и покончил с этим. если вы не делаете достаточно итераций, чтобы это стало огромной проблемой для производительности, просто кодировать проще (и понять, когда вы оглянетесь на это)
$text = 'ignore everything except this (text)'; preg_match('#\((.*?)\)#', $text, $match); print $match[1];
источник
Так, собственно, код размещен не работает:
substr()'s
параметры $ строка, $ начала и $ длина иstrpos()'s
параметры$haystack
,$needle
. Немного изменено:Некоторые тонкости: я использовал
$start + 1
параметр смещения, чтобы помочь PHP приstrpos()
поиске по второй скобке; мы увеличиваем$start
единицу и уменьшаем,$length
чтобы исключить скобки из совпадения.Кроме того, в этом коде нет проверки ошибок: вы захотите убедиться
$start
и$end
не использовать === false перед выполнениемsubstr
.Что касается использования по
strpos/substr
сравнению с регулярным выражением; с точки зрения производительности этот код превзойдет регулярное выражение. Хотя это немного многословнее. Я ем и дышуstrpos/substr
, поэтому я не особо возражаю против этого, но кто-то другой может предпочесть компактность регулярного выражения.источник
Используйте регулярное выражение:
if( preg_match( '!\(([^\)]+)\)!', $text, $match ) ) $text = $match[1];
источник
Это образец кода для извлечения всего текста между '[' и ']' и сохранения его в двух отдельных массивах (т.е. текст внутри круглых скобок в одном массиве и текст вне скобок в другом массиве)
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 () =>, который используется для поиска позиции первого появления в строке.
источник
Уже опубликованные решения с регулярными выражениями -
\((.*?)\)
и\(([^\)]+)\)
- не возвращают самые внутренние строки между открытыми и закрытыми скобками. Если строкаText (abc(xyz 123)
они и возвращают(abc(xyz 123)
как весь матч, а не(xyz 123)
.Шаблон, который соответствует подстрокам (используйте с
preg_match
для получения первой иpreg_match_all
для выборки всех вхождений) в круглых скобках без других открытых и закрывающих круглых скобок между ними, если совпадение должно включать круглые скобки:Или вы хотите получить значения без скобок:
\(([^()]*)\) // get Group 1 values after a successful call to preg_match_all, see code below \(\K[^()]*(?=\)) // this and the one below get the values without parentheses as whole matches (?<=\()[^()]*(?=\)) // less efficient, not recommended
Замените
*
на,+
если между(
и должен быть хотя бы 1 символ)
.Детали :
\(
- открывающая круглая скобка (должна быть экранирована, чтобы обозначить буквальную круглую скобку, поскольку она используется вне класса символов)[^()]*
- ноль или больше символов , кроме(
и)
(обратите внимание , это(
и)
не должны быть экранированы внутри класса символов , как внутри него,(
и)
не может быть использован для указания группирования и рассматриваются в качестве буквальных скобках)\)
- закрывающая круглая скобка (должна быть экранирована, чтобы обозначить буквальную круглую скобку, поскольку она используется вне класса символов).\(\K
Участие в альтернативных матчах регулярных выражений(
и опускают от значения матча (с\K
оператором сброса матча).(?<=\()
- это положительный просмотр назад, который требует, чтобы a(
появлялся сразу слева от текущего местоположения, но(
не добавляется к значению соответствия, поскольку шаблоны просмотра назад (lookaround) не используются.(?=\()
- это положительный просмотр вперед, который требует, чтобы)
символ появлялся сразу справа от текущего местоположения.Код PHP :
$fullString = 'ignore everything except this (text) and (that (text here))'; if (preg_match_all('~\(([^()]*)\)~', $fullString, $matches)) { print_r($matches[0]); // Get whole match values print_r($matches[1]); // Get Group 1 values }
Вывод:
Array ( [0] => (text) [1] => (text here) ) Array ( [0] => text [1] => text here )
источник
function getStringsBetween($str, $start='[', $end=']', $with_from_to=true){ $arr = []; $last_pos = 0; $last_pos = strpos($str, $start, $last_pos); while ($last_pos !== false) { $t = strpos($str, $end, $last_pos); $arr[] = ($with_from_to ? $start : '').substr($str, $last_pos + 1, $t - $last_pos - 1).($with_from_to ? $end : ''); $last_pos = strpos($str, $start, $last_pos+1); } return $arr; }
это небольшое улучшение предыдущего ответа, который вернет все шаблоны в виде массива:
getStringsBetween ('[T] his [] is [test] string [pattern]') вернет:
источник
Я думаю, что это самый быстрый способ получить слова между первой круглой скобкой в строке.
$string = 'ignore everything except this (text)'; $string = explode(')', (explode('(', $string)[1]))[0]; echo $string;
источник