PHP: Best way to extract text within parenthesis?

后端 未结 8 1414
北海茫月
北海茫月 2020-11-28 06:11

What\'s the best/most efficient way to extract text set between parenthesis? Say I wanted to get the string \"text\" from the string \"ignore everything except this (text)\"

相关标签:
8条回答
  • 2020-11-28 06:26
    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; }
    

    this is a little improvement to the previous answer that will return all patterns in array form:

    getStringsBetween('[T]his[] is [test] string [pattern]') will return:

    0 讨论(0)
  • 2020-11-28 06:31

    Use a regular expression:

    if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
        $text = $match[1];
    
    0 讨论(0)
  • 2020-11-28 06:32

    i think this is the fastest way to get the words between the first parenthesis in a string.

    $string = 'ignore everything except this (text)';
    $string = explode(')', (explode('(', $string)[1]))[0];
    echo $string;
    
    0 讨论(0)
  • 2020-11-28 06:37

    i'd just do a regex and get it over with. unless you are doing enough iterations that it becomes a huge performance issue, it's just easier to code (and understand when you look back on it)

    $text = 'ignore everything except this (text)';
    preg_match('#\((.*?)\)#', $text, $match);
    print $match[1];
    
    0 讨论(0)
  • 2020-11-28 06:37

    This function may be useful.

        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() => which is used to find the position of first occurance in a string.

    strrpos() => which is used to find the position of first occurance in a string.

    0 讨论(0)
  • 2020-11-28 06:38

    The already posted regex solutions - \((.*?)\) and \(([^\)]+)\) - do not return the innermost strings between an open and close brackets. If a string is Text (abc(xyz 123) they both return a (abc(xyz 123) as a whole match, and not (xyz 123).

    The pattern that matches substrings (use with preg_match to fetch the first and preg_match_all to fetch all occurrences) in parentheses without other open and close parentheses in between is, if the match should include parentheses:

    \([^()]*\)
    

    Or, you want to get values without parentheses:

    \(([^()]*)\)        // 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
    

    Replace * with + if there must be at least 1 char between ( and ).

    Details:

    • \( - an opening round bracket (must be escaped to denote a literal parenthesis as it is used outside a character class)
    • [^()]* - zero or more characters other than ( and ) (note these ( and ) do not have to be escaped inside a character class as inside it, ( and ) cannot be used to specify a grouping and are treated as literal parentheses)
    • \) - a closing round bracket (must be escaped to denote a literal parenthesis as it is used outside a character class).

    The \(\K part in an alternative regex matches ( and omits from the match value (with the \K match reset operator). (?<=\() is a positive lookbehind that requires a ( to appear immediately to the left of the current location, but the ( is not added to the match value since lookbehind (lookaround) patterns are not consuming. (?=\() is a positive lookahead that requires a ) char to appear immediately to the right of the current location.

    PHP code:

    $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
    }
    

    Output:

    Array ( [0] => (text)  [1] => (text here) )
    Array ( [0] => text    [1] => text here   )
    
    0 讨论(0)
提交回复
热议问题