LoginSignup
4
3

More than 5 years have passed since last update.

括弧の対応をチェックするアレをtoken_get_allを使ってしれっと適当に書いてみる

Last updated at Posted at 2015-05-30

知恵袋を覗いていたら、書いてみたいコードがあったが、回答を書き込んでしまって質問を閉じられると、他の人のコードも見れないには嫌だなと思ったので、こちらにしれっと書いてみる。

token_get_allを使ってみたくて、関数を書いてみました。
細かくテストしてないので、バグがあったら教えてください( ´ ▽ ` )ノ

ちなみにstackoverflowでも似たような質問がありました。

Matching braces puzzle

PHP
<?php
/**
 * check matching of braces
 * 
 * @param string $src     target string to check
 * @return bool
 */
function brace_check($src)
{
    $open_braces = str_split("({[");
    $close_braces = str_split(")}]");
    $braces = array_merge($open_braces, $close_braces);

    $tokens = token_get_all('<?php '.$src);
    // bracesを含むであろう文字列トークン以外は捨てる
    $tokens = array_filter($tokens,function($item){ return is_string($item); });

    $open_brace_stack = array();
    foreach($tokens as $key => $t){
        if (in_array($t,$open_braces)){
            // 開括弧なら開括弧スタックに乗せる
            array_push( $open_brace_stack, $t);
        }
        elseif (in_array($t,$close_braces)){
            if ( empty($open_brace_stack) ){
                // 開括弧スタックが空ならエラー
                return false;
            }
            // 括弧の対応を確認(開括弧スタックのトップと現在の文字)
            $open_top = array_pop($open_brace_stack);
            $idx_open = array_search($open_top, $open_braces);
            $idx_close = array_search($t, $close_braces);
            if ( $idx_open !== $idx_close ){
                return false;
            }
        }
    }
    return true;
}

//=========================
// test code

$html_case = <<<HTML
<?php
?>
<html>
...
<ul>
<li>1)...</li>
<li>2)...</li>
</ul>
...
<?php
...
?>
...
</html>
HTML;

$expressions = array(")(){}","[]({})","([])","{()[]}","([)]",$html_case);

var_dump(array_map('brace_check', $expressions));
4
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3