Reputation: 536
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
Reputation: 89557
with pcre (PHP, R) you can do that:
\G(?:\A[^.]*\.)?+[^.]*\K\.
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)
(?<!^[^.]*)\.
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
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