Q:

Java Regex to regex to remove double hyphens and keep single ones

So I need a regular expression that removes all non-word characters(except for spaces and hyphens) from text, so I can count the number of words in the text. 
Something like 
String().replaceAll("[^\\p{L}+(?:\\-\n?\\p{L}+)* ]", "")

mostly works, as it keeps hyphenated words but a problem arises when I get a double hyphen. A double hyphen in American English is supposed to represent a single dash, so in my case I'd need to replace it with a space as well. Does anyone know how to modify it so that doesn't happen?
Here's an example. The following sentence:
While I was off-campus, I lost all my belongings--wallet, keys, everything!
Should look like this after the regex:
While I was off-campus I lost all my belongings wallet keys everything
EDIT - I'm not interested in using two replaceAlls, I want to do it in a single regex.

A:

Your original regex is broken, since (?:...) and *, + are treated as literal character inside a character class [].
In a character class in Java, [, ], \ (for escape sequences and properties), \Q, \E (for quoting special characters in character class), ^ (effective only at beginning of class), - (effective between 2 characters), && (for character class intersection) are the only characters/sequences with special meaning.
You can test your regex against this example string to confirm what I said above.
This is another example: (parentheses) + [brackets] + (asterisks *)
Instead of removing invalid characters and stuffs, you can just match the words directly with this regex (the part inside the character class of your regex):
"\\p{L}+(?:-\n?\\p{L}+)*"

The regex above can be used in a Matcher loop to count the number of words:
Pattern p = Pattern.compile("\\p{L}+(?:-\n?\\p{L}+)*");
Matcher m = p.matcher(input);
int count = 0;

while (m.find()) {
   count++;
}

If you still want to replace all characters not matching the definition of a "word" as defined in the regex above:
input.replaceAll("(?s).*?(\\p{L}+(?:-\n?\\p{L}+)*)|.+", "$1 ");

(?s).*?(\\p{L}+(?:-\n?\\p{L}+)*) searches for non-"word" characters before a "word", and remove them, and a space is added after the "word". The .+ at the end deals with sequence of non-"word" characters at the end of the string.
Note that it will produce a trailing space if the last character is not part of a "word".
Demo on regex101
Test input:
While I was off-campus, I lost all my belongings--wallet, keys, everything!

This is another example: (parentheses) + [brackets] + (asterisks *)

Along-
longl-
onglo-
ngword!

Test output (note the trailing space at the end):
While I was off-campus I lost all my belongings wallet keys everything This is another example parentheses brackets asterisks Along- longl- onglo- ngword 

If you are asking whether I can eliminate the trailing space by modifying the regex above, I'd say not possible in Java. The problem here is that -- must be replaced with a space to separate the 2 "word"s, while other non-"word" characters must be replaced with an empty string.

