PHP:在括号内提取文本的最佳方法?

Wil*_*lco 71 php string parsing

在括号之间提取文本集的最佳/最有效方法是什么?假设我想以最有效的方式从字符串"忽略除此(文本)之外的所有内容"中获取字符串"text".

到目前为止,我提出的最好的是:

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

$shortString = substr($fullString, $start, $end);
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?我知道通常使用正则表达式往往效率较低,但除非我可以减少函数调用的数量,否则这可能是最好的方法吗?思考?

Owe*_*wen 122

我只是做一个正则表达式并完成它.除非你做了足够的迭代以致它成为一个巨大的性能问题,它只是更容易编码(并且当你回顾它时理解)

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

  • 很高兴知道。应该避免所有这些平方数。例如 /src="([^"]*)"/ 现在替换为 /src="(.*?)"/ :D (2认同)
  • / src ="([^"]*)"/比/src="(.*?)"/更有效 (2认同)

Edw*_*ang 12

所以,实际上,你发布的代码不起作用: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,所以我不太介意,但其他人可能更喜欢正则表达式的紧凑性.

  • 请注意,如果您修改此代码以在 $end 上使用 strrpos (从字符串的后面开始),那么它将正确处理其中有括号的情况.. 就像(这(非常)好)。 (3认同)

Rob*_*Rob 9

使用正则表达式:

if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
    $text = $match[1];
Run Code Online (Sandbox Code Playgroud)


rüf*_*ff0 8

我认为这是获取字符串中第一个括号之间的单词的最快方法。

$string = 'ignore everything except this (text)';
$string = explode(')', (explode('(', $string)[1]))[0];
echo $string;
Run Code Online (Sandbox Code Playgroud)


Wik*_*żew 5

已经发布的正则表达式解决方案 -\((.*?)\)\(([^\)]+)\)- 不会返回左括号和右括号之间的最里面的字符串。如果字符串是,则Text (abc(xyz 123)它们 返回(abc(xyz 123)整个匹配项,而不是返回(xyz 123)

preg_match如果匹配应包含括号,则匹配括号中的子字符串(使用 with来获取第一个并preg_match_all获取所有出现的位置)而中间没有其他左括号和右括号的模式是:

\([^()]*\)
Run Code Online (Sandbox Code Playgroud)

或者,您想要获取不带括号的值:

\(([^()]*)\)        // 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
Run Code Online (Sandbox Code Playgroud)

如果和之间必须至少有 1 个字符,则替换*为。+()

细节

  • \(- 左圆括号(必须转义以表示文字括号,因为它在字符类外部使用)
  • [^()]*-除and之外的零个或多个字符(请注意,这些and不必在字符类内部进行转义,并且不能用于指定分组并被视为文字括号)()()()
  • \)- 右圆括号(必须转义以表示文字括号,因为它在字符类外部使用)。

\(\K替代正则表达式中的部分匹配并(从匹配值中省略(使用\K匹配重置运算符)。(?<=\()是正向回顾,要求 a(立即出现在当前位置的左侧,但(不会添加到匹配值,因为回顾(环视)模式不消耗。(?=\()是一个正向前瞻,要求一个)字符立即出现在当前位置的右侧。

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
}
Run Code Online (Sandbox Code Playgroud)

输出:

Array ( [0] => (text)  [1] => (text here) )
Array ( [0] => text    [1] => text here   )
Run Code Online (Sandbox Code Playgroud)