# Split regex behavior

**URL:** <https://discuss.kakoune.com/t/split-regex-behavior/831>\
**Category:** Help\
**Created:** [January 3, 2020, 6:13pm UTC](https://discuss.kakoune.com/t/split-regex-behavior/831 "2020-01-03T18:13:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![FlyingWombat](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/flyingwombat/32/120_2.png) [@FlyingWombat](https://discuss.kakoune.com/u/FlyingWombat)\
**Post date:** [January 3, 2020, 6:13pm UTC](https://discuss.kakoune.com/t/split-regex-behavior/831/1 "2020-01-03T18:13:50Z")

</div>

For split `S`, I originally thought it was just the inverse of select `s`.  
Where the selections would be all that doesn’t match the regex.  
( `-` selected char, `+` secondary cursor, `^` primary cursor)

```auto
foo,bar
--+ --^
~
split:,

```

But I don’t get why this happens: where some matches of the regex are selected.

```auto
abbba baaab
+--+ -+ ++^
~
split:a

```

I would have thought that `split:a` on `abba` would select the inverse of the regex (select only the b’s and spaces), like this:

```auto
abbba baaab
 --+ -+ ^
~
split:a

```

Feature or Bug? Thoughts?

---

<div class="post-metadata">

**Author:** ![prion](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/prion/32/404_2.png) [@prion](https://discuss.kakoune.com/u/prion)\
**Post date:** [January 4, 2020, 12:13am UTC](https://discuss.kakoune.com/t/split-regex-behavior/831/2 "2020-01-04T00:13:34Z")

</div>

The behavior is more obvious if you type something after performing the split

```auto
abbba baaab
# split: a
# i_
_a_bbba_ ba_a_a_b

```

As you can see it splits the current selection into smaller sub-sections (meaning it retains the current anchor & cursor) by ending the current selection when it meets the regex.

Position 0: start selection  
Position 1: matches regex, end selection. Cursor must go on the `a` character as it is 0 width selection.  
Position 2,3,4: continue selection.  
Position 5: matches regex so stop selection…

I’m just guessing here but the weird cursor behavior where it sometimes ends up on an “a” seems to be due to have a “0 width selection” between each a. If you split on `a+` you get something close to what you expected.

If you want to achieve an inverse selection then you can either do this to select anything that’s at least one character long where all of the characters are not a (written `^a`)

```auto
abbba baaab
# select: [^a]+
abbba baaab
 --+ -+ ^
# a*
abbb*a b*aaab*

```

you can also do a zero-width negative lookahead but then I think you have to do a merge afterwards, unless someone else knows how to do it all at once

```auto
abbba baaab
# select: (?!a)
abbba baaab
 +++ ++ ^
# <a-_> (a.k.a. Alt-Underscore)
abbba baaab
 --+ -+ ^
# a*
abbb*a b*aaab*

```

As an aside if you do an append after the `split: a` rather than an insert then you almost get the behaviour of the inverse selection but you also end up with a cursor at the end of you selection, which you probably don’t want.

---

<div class="post-metadata">

**Author:** ![FlyingWombat](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/flyingwombat/32/120_2.png) [@FlyingWombat](https://discuss.kakoune.com/u/FlyingWombat)\
**Post date:** [January 6, 2020, 11:17pm UTC](https://discuss.kakoune.com/t/split-regex-behavior/831/3 "2020-01-06T23:17:05Z")

</div>

I think you’re right about it being 0-width selections between matches.  
I haven’t looked at the code, but now that you mention it, I’d guess it just places a cursor before each match, and an anchor after.

`((?!expr).)+` gives an inverted match, for simple expressions, but chokes on more complicated ones. For example: an expression to select brackets with text `\[.*?\]` does not work with the negative lookahead, since “Quantifiers cannot be used in lookarounds”.

The annoying thing is, I could see use-cases for either side: where sometimes you’d want cursors in between adjacent matches (current behavior), and sometimes you wouldn’t (inverted select).

I’d be interested to know which the intention was, for the code design.

---

<div class="post-metadata">

**Author:** ![FlyingWombat](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/flyingwombat/32/120_2.png) [@FlyingWombat](https://discuss.kakoune.com/u/FlyingWombat)\
**Post date:** [January 7, 2020, 2:06am UTC](https://discuss.kakoune.com/t/split-regex-behavior/831/4 "2020-01-07T02:06:15Z")

</div>

Oh, I just realized, you were right again, using the `+` quantifier (almost) gives the “inverse match” behavior I was expecting.  
Just surround the expression with a capturing group, and add the `+` quantifier `(expr)+`  
A more complex example:

```auto
[]foo[bar][]asdf[qwer]
+ --+ ---+
~
split:(\[.*?\])+

```

There’s still a pesky cursor at the beginning, when there’s a match starting at pos 0. And again, there are times you might want that, and times you might not.
