import re


def note_str_to_num(note, base_octave=-1):
    """Convert note pitch as string to MIDI note number."""
    patt = re.match('^([CDEFGABcdefgab])([b#]*)(-?)(\d+)$', note)
    if patt is None:
        raise ValueError('invalid note string "{}"'.format(note))
    base_map = {'C': 0,
                'D': 2,
                'E': 4,
                'F': 5,
                'G': 7,
                'A': 9,
                'B': 11}
    base, modifiers, sign, octave = patt.groups()
    base_num = base_map[base.upper()]
    mod_num = -modifiers.count('b') + modifiers.count('#')
    sign_mul = -1 if sign == '-' else 1
    octave_num = 12*int(octave)*sign_mul - 12*base_octave
    note_num = base_num + mod_num + octave_num
    if note_num < 0 or note_num >= 128:
        raise ValueError('note string "{}" resulted in out-of-bounds note number {:d}'.format(note, note_num))
    return note_num