gabrielgeo
gabrielgeo

Reputation: 536

Regular expression match all except first occurence

I need a regular expression to match all occurrences of a dot (.) except the first one.

For example if the source is: aaa.bbb.ccc..ddd

the expression should match the dots after bbb and ccc but not the dot after aaa. In other works it should match all dots except the first one.

I need it for javascript regex.

Upvotes: 6

Views: 13424

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

with pcre (PHP, R) you can do that:

\G(?:\A[^.]*\.)?+[^.]*\K\.

demo

details:

\G # anchor for the start of the string or the position after a previous match
(?:\A[^.]*\.)?+ # start of the string (optional possessive quantifier)
[^.]* # all that is not a dot
\K    # remove all that has been matched on the left from the match result
\.    # the literal dot

With .net: (easy since you can use a variable length lookbehind)

(?<!^[^.]*)\.

demo


With javascript there is no way to do it with a single pattern.

using a placeholder:

var result = s.replace('.', 'PLACEHOLDER')
              .replace(/\./g, '|')
              .replace('PLACEHOLDER', '.');

(or replace all dots with | and then replace the first occurrence of | with a dot).

using split:

var parts = s.split('.');
var result = parts.shift() + (parts.length ? '.': '') + parts.join('|');

with a counter:

var counter = 0;
var result = s.replace(/\./g, (_) => counter++ ? '|' : '.');

With NodeJS (or any other implementation that allows lookbehinds):

var result = s.replace(/((?:^[^.]*\.)?(?<=.)[^.]*)\./g, "$1|");

Upvotes: 10

Maxime Lechevallier
Maxime Lechevallier

Reputation: 1186

One-line solution for JavaScript using arrow function (ES6):

'aaa.bbb.ccc..ddd'
   .replace(/\./g, (c, i, text) => text.indexOf(c) === i ? c : '|')

-> 'aaa.bbb|ccc||ddd'

Upvotes: 7

Related Questions