input: Write a python function to tokenize a string based on predefined patterns.
  assert lex('[10.5 hello]') == [('OPEN_BRACE', '['), ('NUMBER', '10.5'), ('TEXT', 'hello'), ('CLOSE_BRACE', ']')]
  assert lex('123 [ world]') == [('NUMBER', '123'), ('OPEN_BRACE', '['), ('TEXT', 'world'), ('CLOSE_BRACE', ']')]
  assert lex('foo [42]') == [('TEXT', 'foo'), ('OPEN_BRACE', '['), ('NUMBER', '42'), ('CLOSE_BRACE', ']')]
output: import re
  
  def lex(s):
      token_specification = [
          ('NUMBER',    r'\d+(\.\d*)?'),  # Integer or decimal number
          ('OPEN_BRACE', r'\['),          # Open brace
          ('CLOSE_BRACE', r'\]'),         # Close brace
          ('TEXT',      r'\w+'),          # Identifiers
          ('SKIP',      r'[ \t]+'),       # Skip over spaces and tabs
      ]
  
      tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
      get_token = re.compile(tok_regex).match
      pos = 0
      tokens = []
      mo = get_token(s)
      while mo is not None:
          typ = mo.lastgroup
          if typ != 'SKIP':
              val = mo.group(typ)
              tokens.append((typ, val))
          pos = mo.end()
          mo = get_token(s, pos)
      return tokens