The \\p{C}
regex takes care of all non-printable characters. Be aware that this includes tabs and newlines.
As for Emoji characters, that a bit more complicated. You could just match the newer Emoji characters in Unicode, i.e. Unicode Block 'Emoticons' (U+1F600 to U+1F64F), but that's not really all the Emoji characters, e.g. ❤ 'HEAVY BLACK HEART' (U+2764) is not in that range.
If you look at those Emoji characters, e.g. 'GRINNING FACE' (U+1F600), you'll see that it belongs to Unicode Category "Symbol, Other [So]", which consists of 5855 characters. If you're ok removing all those, that would definitely be the easiest solution.
Your text included a red heart (❤️), not a black heart (❤), and that is done in Unicode by adding a variation selector after the black heart, e.g. a 'VARIATION SELECTOR-16' (U+FE0F) in this case. There are 256 variation selectors, and they are all in category Mark, Nonspacing [Mn], but you probably don't want to remove all 1763 of those, so you need to remove the 2 ranges of variation selectors, i.e. U+FE00 to U+FE0F (selectors 1-16) and U+E0100 to U+E01EF (selectors 17-256).
After that, you may or may not want to reduce consecutive spaces to a single space.
str = str.replaceAll("[\\p{C}\\p{So}\uFE00-\uFE0F\\x{E0100}-\\x{E01EF}]+", "")
.replaceAll(" {2,}", " ");