If the inner text inside the ${...;...} cannot contain {, } and ; use a negated character class solution:
\$\{([^;{}]*);\s*([^{};]*)}
See the regex demo.
If the plan is to match word chars only you may simplify it to
\$\{(\w+)\s*;\s*(\w+)}
See another regex demo.
Details
\$\{ - a ${ substring
([^;{}]*) - Group 1: any 0+ chars other than ;, { and } ((\w+) would match 1 or more word chars, letters, digits, underscores)
\s*;\s* - a ; enclosed with 0+ whitespaces
([^;{}]*) - Group 2: any 0+ chars other than ;, { and }
} - a } char.
Java demo:
String s = "Test 123 ${tag1} lorem ipsum ${tag2} ${tag3; tag4} ${tag5; tag6} dixit lorem ${tag7} dixit lorem ${tag8}.";
Pattern pattern = Pattern.compile("\\$\\{(\\w+)\\s*;\\s*(\\w+)}");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println("=== END OF MATCH ===");
}
Output:
${tag3; tag4}
tag3
tag4
=== END OF MATCH ===
${tag5; tag6}
tag5
tag6
=== END OF MATCH ===