You can use
If what you want to capture can't have a ?
in it, use a negated character class [^...]
(see demo here):
^([^\s?]+)\??$
If what you want to capture can have ?
in it (for example, yolo?yolo?
and you want
yolo?yolo
), you need to make your quantifier +
lazy by adding ?
(see demo here):
^(\S+?)\??$
There is BTW no need for a capturing group here, you can use a look ahead (?=...)
instead and look at the whole match (see demo here):
^[^\s?]+(?=\??$)
What was happening
The rules are: quantifiers (like +
) are greedy by default, and the regex engine will return the first match it finds.
Considers what this means here:
\S+
will first match everything in yolo?
, then the engine will try to match (?:\?$|$)
.
\?$
fails (we're already at the end of the string, so we now try to match an empty string and there's no ?
left), but $
matches.
The regex has succesfully reached its end, the engine returns the match where \S+
has matched all the string and everything is in the first capturing group.
To match what you want you have to make the quantifier lazy (+?
), or prevent the character class (yeah, \S
is a character class) from matching your ending delimiter ?
(with [^\s?]
for example).