A simple template engine to display value
1. Introduction

This code looks mostly fine to me. I make a bunch of points below, but it's a case of tightening things up rather than fixing mistakes.

2. Review


The Template class is misleadlingly named. Normally the term template refers to the string into which the parameters are substituted. But an instance of the Template class actually represents the settings controlling the substitution. A better name for the class would be TemplateProcessor.
Since the only thing you can do with a Template object is to call its substitute method, it would simplify things to use __call__ instead.
The parameter name template to the substitute function is misleadingly named: this isn't the template, but actually the parameters to be substituted into the template. A better name would be params.
It would be simpler to take the substitution parameters as keyword arguments rather than a dictionary. This would slightly simplify the callers because instead of writing:

processor(string, {'var': 'Try'})


you could write:

processor(string, var='Try')

The value of result is a match object and so match or m would be a better name.
The code takes four steps to match a word against the syntax rules:

if word.startswith(self.delimiter_start) \
        and word.endswith(self.delimiter_end):
            word_without_delimiter = word[1:-1]
            result = re.match(
                self.identifier, word_without_delimiter)


But this could all be done in a single step using a regular expression that matches the initial delimiter, the identifer or nonidentifier, and the final delimiter: that is,

\[(?:([^\d\W]\w*)|(.*))\]$


See the revised code below for how this regular expression can be built and used.
The error message ought to include the incorrect identifier, for assistance with debugging.
Instead of:

'{value}'.format(value=template[word_without_delimiter])


use the format function and write:

format(template[word_without_delimiter])



3. Revised code

(Docstrings omitted—they were fine in the original.)

class TemplateProcessor(object):
    def __init__(self, delimiter_start='[', delimiter_end=']',
                 identifier=r'[^\d\W]\w*'):
        self.identifier_re = re.compile(
            '{}(?:({})|(.*)){}$'.format(re.escape(delimiter_start),
                                        identifier,
                                        re.escape(delimiter_end)),
            re.UNICODE)

    def __call__(self, string, **params):
        words = string.split(' ')
        for i, word in enumerate(words):
            m = self.identifier_re.match(word)
            if not m:
                continue
            identifier, nonidentifier = m.groups()
            if identifier is None:
                raise ValueError("{!r} is not a valid identifier"
                                 .format(nonidentifier))
            elif identifier in params:
                words[i] = format(params[identifier])
        return ' '.join(words)