guroosh
guroosh

Reputation: 652

Formatting text in sublime using regex

I want to format my file containing keywords which is alphabetically sorted, something like this:

...
national day
national
other
random
random2
...

and i want to put a space between keywords starting with different alphabets (meaning space between a's and b's and so on), which will look something like this:

...
national day
national

other

random
random2
...

I am doing this using regex and the regex which I tried is \n(.{1,1})(?:.*?)\n(?!\1). This works fine for most cases except when there is only one occurrence of a keyword from one alphabet, in this case other. Link to regex.

As it can be seen national and random2 are matching but other is not, although I believe there is every reason for it to.

The regex which works is ^(.{1,1})(?:.*?)\n(?!\1) (first \n replaced by a ^) but I need a reason for why is the first regex not matching with other. Thank you.

Upvotes: 1

Views: 212

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626690

Your regex consumes both newlines before and after that line. On the demo below, pay attention how the engine skips the other line:

enter image description here

You may fix the pattern with another lookaround, a (?<=\n) positive lookbehind: (?<=\n)(.).*\n(?!\1), see demo.

However, you may use a more "linear" pattern with no lookarounds:

^(.).*(?:\n\1.*)*

Or if \R is supported:

^(.).*(?:\R\1.*)*

Replace with $0\n. See the regex demo.

Details

  • ^ - start of a line
  • (.) - Capturing group 1: any char other than a line break char
  • .* - the rest of a line
  • (?:\n\1.*)* - zero or more repetitions of
    • \n - a newline
    • \1 - same char as in Group 1
    • .* - the rest of the line.

Replace \n with \R to match any linebreak sequence.

Upvotes: 1

Related Questions