Разбор токенов с помощью Regex в PHP - PullRequest
2 голосов
/ 17 ноября 2010

Я хочу проанализировать файл токена, который выглядит примерно так, как показано ниже, чтобы получить пару имя / значение токена.Отношения токен / значение / вложение уже определены, поэтому я не могу изменить способ создания файлов токенов.Может показаться, что грамматика без контекста может быть лучшим способом, но у меня нет опыта в написании или реализации.Можно ли сделать это с помощью регулярных выражений?Мне не повезло с вложенными многострочными токенами (такими как Master1, Servant2).

;token1 = I am a top level single line token  
;token2 {  
    I am a top level  
    multiline line token  
}  

master1 {  
;servant1 = I am Master1, Servant1 single line token  
;servant2 {  
    I am Master1, Servant2.   
    A mulit line token.  
}  
;servant3 = I am Master1, Servant3  
}  
master2 {  
;servant1 = I am Master2, Servant1  
;servant2 {  
    I am Master2, Servant2  
A mulit line token.  
}  
;servant3 = I am Master2, Servant3  
}

Ответы [ 2 ]

3 голосов
/ 17 ноября 2010

PHP имеет функцию для токенизации строк с помощью

  • strtok - разбивает строку (str) на меньшие строки (токены), причем каждый токен являетсяотграниченный любым символом от токена.То есть, если у вас есть строка типа «Это пример строки», вы можете разбить эту строку на отдельные слова, используя символ пробела в качестве токена.
2 голосов
/ 17 ноября 2010

Вот довольно простой анализатор обхода строк (изначально я пытался написать для него регулярное выражение, но отсутствие начального ; в начале многострочного мастера действительно сильно усложнило (без этого ; отсутствует, это достаточно просто написать). Я сдался и написал это):

function getTokens($string) {
    $string = trim($string);;
    $lines = explode("\n", $string);
    $data = array();
    $key = '';
    $open = 0;
    $buffer = '';
    foreach ($lines as $line) {
        $line = trim($line);
        if (empty($line)) {
            continue;
        } elseif (strpos($line, '}') === 0) {
            $open--;
            if ($open == 0) {
                $data[$key] = getTokens($buffer);
                $buffer = '';
            } elseif ($open < 0) {
                throw new Exception('Unmatched }');
            } else {
                $buffer .= "\n" . $line;
            }
        } elseif ($open > 0) {
            if (strpos($line, '{') !== false) {
                $open++;
            }
            $buffer .= "\n" . $line;
        } elseif ($line[0] == ';') {
            if (strpos($line, "=") !== false) {
                list ($key, $value) = explode("=", $line, 2);
                $key = trim(substr($key, 1));
                $value = trim($value);
                $data[$key] = $value;
            } elseif (strpos($line, "{") !== false) {
                $open++;
                list ($key, $value) = explode("{", $line, 2);
                $key = trim(substr($key, 1));
            } else {
                throw new Exception('Unmatched token ;');
            }
        } elseif (strpos($line, '{') !== false) {
            $open++;
            list ($key, $value) = explode("{", $line, 2);
            $key = trim($key);
        } else {
            $buffer .= "\n" . $line;
        }
    }
    if ($open > 0) {
        throw new Exception('Unmatched {');
    } elseif (empty($data) && !empty($buffer)) {
        return trim($buffer);
    }
    return $data;
}

Когда я передаю эту строку в качестве ввода, я получаю:

Array(
    "token1" => "I am a top level single line token",
    "token2" => "I am a top level
                    multiline line token",
    "master1" => Array(
        "servant1" => "I am Master1, Servant1 single line token",
        "servant2" => "I am Master1, Servant2.
                            A mulit line token.",
        "servant3" => "I am Master1, Servant3",
    ),
    "master2" => Array(
        "servant1" => "I am Master2, Servant1",
        "servant2" => "I am Master2, Servant2
                            A mulit line token.",
        "servant3" => "I am Master2, Servant3",
    ),
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...