Question: So, here is the pattern

```
^(.*)\..*$|^(.*)$

```

Test strings:
 1. file.tar.gz
 2. file

For first test I would get the 'file.tar' in 'group 1' and 'file' in 'group 2'. But I want the output in only one group. I can't come up any other pattern. Not even sure if it is possible.

Answer: 
You need to make the first `.*` lazy, and use a negated character class inside an optional group:

```
^(.*?)(?:\.[^.]*)?$

```

See the [regex demo](https://regex101.com/r/0mewXL/1)

**Details**:

* `^` - start of string
* `(.*?)` - any 0+ chars as few as possible
* `(?:\.[^.]*)?` - an optional non-capturing group matching 1 or 0 sequences of:
	+ `\.` - a dot
	+ `[^.]*` - 0+ chars other than `.`
* `$` - end of string.
An other way using a double negation and without a capture group:

```
^.*(?![^.])

```

*(any number of characters from the start of the string, that is not followed by a character that isn't a dot.)*

"not followed by a character that isn't a dot" <=> "followed by a dot or the end of the string"

[demo](https://regex101.com/r/ay5FTa/1)