在括号之间提取文本集的最佳/最有效方法是什么?假设我想以最有效的方式从字符串“忽略除此(文本)之外的所有内容”中获取字符串“text”。
到目前为止,我提出的最好的是:
$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);
$shortString = substr($fullString, $start, $end);
有更好的方法吗?我知道通常使用正则表达式往往效率较低,但除非我可以减少函数调用的数量,否则这可能是最好的方法吗?想法?
答案 0 :(得分:114)
我只是做一个正则表达式并完成它。除非你做了足够多的迭代以致它成为一个巨大的性能问题,它只是更容易编码(当你回顾它时理解它)
$text = 'ignore everything except this (text)';
preg_match('#\((.*?)\)#', $text, $match);
print $match[1];
答案 1 :(得分:12)
所以,实际上,您发布的代码不起作用:substr()'s
参数是$ string,$ start和 $ length ,strpos()'s
参数是{{1 },$haystack
。略有修改:
$str = "ignore everything except this (text)"; $start = strpos($str, '('); $end = strpos($str, ')', $start + 1); $length = $end - $start; $result = substr($str, $start + 1, $length - 1);
一些细微之处:我在offset参数中使用了$needle
,以便在第二个括号中进行$start + 1
搜索时帮助PHP输出;我们增加strpos()
一个并减少$start
以从匹配中排除括号。
此外,此代码中没有错误检查:在执行$length
之前,您需要确保$start
和$end
不要=== false。
至于使用substr
与正则表达式相比;在性能方面,这段代码将击败正则表达式。虽然这有点讽刺。我吃饭和呼吸strpos/substr
,所以我不太介意,但其他人可能更喜欢正则表达式的紧凑性。
答案 2 :(得分:8)
使用正则表达式:
if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
$text = $match[1];
答案 3 :(得分:3)
这是一个示例代码,用于提取'['和']'之间的所有文本,并将其存储为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"
}
答案 4 :(得分:1)
此功能可能很有用。
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()=&gt;用于查找字符串中第一次出现的位置。
strrpos()=&gt;用于查找字符串中第一次出现的位置。
答案 5 :(得分:0)
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 []是[test]字符串[pattern]')将返回:
答案 6 :(得分:0)
已经发布的正则表达式解决方案-\((.*?)\)
和\(([^\)]+)\)
-在左括号和右括号之间不返回 innermost 字符串。如果字符串是Text (abc(xyz 123)
,则它们将both return整个匹配为(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个字符,请用(
替换)
。
详细信息:
\(
-圆括号(必须转义以表示文字括号,因为它在字符类外部使用)[^()]*
-zero or more除(
和)
以外的其他字符(请注意,这些(
和)
不必在字符类,(
和)
不能用于指定分组,并被当作文字括号)\)
-右括号(必须转义以表示文字括号,因为它在字符类外部使用)。备用正则表达式中的\(\K
部分与(
匹配,并且从匹配值中省略(使用\K
匹配重置运算符)。 (?<=\()
是正向后看,要求(
必须立即显示在当前位置的左侧,但是(
不会添加到匹配值中,因为不会使用向后看(lookaround)模式消耗。 (?=\()
是积极的前瞻,需要)
字符才能立即显示在当前位置的右侧。
$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 )
答案 7 :(得分:0)
我认为这是在字符串的第一个括号之间获取单词的最快方法。
$string = 'ignore everything except this (text)';
$string = explode(')', (explode('(', $string)[1]))[0];
echo $string;