As stated by ctn The problem with the non-greedy modifier as stated in your regex is that it starts looking for the first definition of typedef and will stop at the first place where it finds structA. Everything in between is considered as valid. A way to use regex to solve your problem is to define a regex which identifies the structs, and later in a separate stage you verify if the match corresponds to the struct that you want.
For example, using the regex:
(typedef[\s\S]+?})\s*([a-zA-Z0-9_]+)\s*;
you will define 2 groups, where the first starts at a typedef and ends at a curly brace, with a non-greedy text matching. This first group contains the string that you might want. The final curly brace is followed by the struct name ([a-zA-Z0-9_]+) and ends with ;. Considering your example, there will be 2 matches, each containing 2 groups.
Match 1:
(typedef struct
{
})(dontMatchThis);
Value of group 2: dontMatchThis
Match 2:
(typedef struct
{
  union //lets have a union as well
  {
    struct 
    {
     int a
     //a comment for fun
     int b;
     int c;
    };
    char byte[10];
  };
})(structA);
Value of group 2: structA
Thus, it becomes a matter of verifying if the value of the group 2 corresponds to structA.