Skip to main content


Calling all #regex witches and warlocks!

I want to match individually each space at the beginning of each line of the input text. I do not want to match any other space.

Text input:

Baseline of this text
  Indentation with two spaces
    Surprise, the text has two  spaces too!

Target syntax: PCRE2 (PHP >= 7.3)
Expected matches: 6

So far my best attempt is /(?<=^| ) /m but it also matches spaces beyond the first in any series of two or more consecutive spaces anywhere in the text, not just at the beginning of each line. See https://regex101.com/r/GXfJL0/1

Can you do better?

I tried to add a negative lookbehind in the space of the lookahead. Don't know if there are any unexpected case

/(?<=^|(?<![^\s]) ) /mg

https://regex101.com/r/SEAu43/1
/(?:^|\G) /mg, but there's probably a non-stupid way to do whatever you're trying to achieve.
@Locrian Filth Wow, thank you, it’s perfect, I didn’t know about \G!
@Locrian Filth It looks like a positive lookbehind produces the same result in about 3 times fewer steps than a non-capturing group, but the key definitely is \G.
I'm familiar with sed regex on linux so I gave this a try. Let me know if this does what you need:

/^ +/mg
@Rokosun Thank you for your answer, unfortunately, this matches all the spaces at the beginning of lines at once, which prevents me from replacing individual spaces with another character.
That is more puzzling than I thought, I did some digging around but couldn't find anything that works. Let me know what regex you ended up using to achieve this, I'm curious.

@Rokosun I was given the final clue by @Locrian Filth in https://infosec.exchange/@barubary/110099448284247487 with the \G macro that matches the previous match. This way I can match spaces at the start of a line, and then all the spaces after who are individually matched in order thanks to \G. Other strings of consecutive spaces aren't matched because the first space in the string isn't matched.

Final regular expression: /(?<=^|\G) /m


/(?:^|\G) /mg, but there's probably a non-stupid way to do whatever you're trying to achieve.

Isn't this a simple case of `/^ /`? The `^` matches the start of the line, the space matches the first space. Nothing else needs to match, right?
@Martijn Vos The quirk is that I want to match each space individually to replace them with another character. If I match variable length strings of consecutive spaces, I can't replace them by the corresponding number of replacing characters.
@Hypolite Petovan I have no idea why I've never encountered these lookahead/lookbehind features in my decades of using regex. I learned a new thing today.
This entry was edited (2 years ago)
@Martijn Vos For me, non-capturing groups were the gateway drug to lookahead/lookbehind.
⇧