quick question: my pattern is an svg string and it looks like l 5 0 l 0 10 l -5 0 l 0 -10
To do some unittest comparison against a reference I need to ditch all but the first l
I know i can ditch them all and put an 'l' upfront, or I can use substrings. But I'm wondering is there a javascript regexp idiom for this?
-
Is the first l always at the start of the string? – Mark Byers Oct 31 '11 at 21:32
-
i know you said you don't want this, but substring up to the first space seems like the easiest to read and maintain. – Randy Oct 31 '11 at 21:36
-
@Mark yes for this usecase, it is even ' l', but that also works with the negative lookahead. – dr jerry Oct 31 '11 at 21:49
-
@Randy yes I know, but I wanted to deepen my knowledge on regexps. Your point about readability and maintainability is something to consider. I'll start with commenting. – dr jerry Oct 31 '11 at 21:49
6 Answers
You can try a negative lookahead, avoiding the start of the string:
/(?!^)l/g
See if online: jsfiddle

- 811,555
- 193
- 1,581
- 1,452
-
I'm trying to modify this to work for the first '-' character that appears, and I'm having a very difficult time of it :(. Any help is appreciated. Thanks in advance. – Grant Robert Smith Mar 08 '17 at 23:55
-
-
@GrantRobertSmith I know this is way late, but I provided an answer that covers what I think you're looking for. – Erutan409 Mar 13 '18 at 14:39
-
9This only works if the first `l` is also at the start of the string. – Supernormal Apr 28 '20 at 03:34
There's no JS RegExp to replace everything-but-the-first-pattern-match. You can, however, implement this behaviour by passing a function as a second argument to the replace
method.
var regexp = /(foo bar )(red)/g; //Example
var string = "somethingfoo bar red foo bar red red pink foo bar red red";
var first = true;
//The arguments of the function are similar to $0 $1 $2 $3 etc
var fn_replaceBy = function(match, group1, group2){ //group in accordance with RE
if (first) {
first = false;
return match;
}
// Else, deal with RegExp, for example:
return group1 + group2.toUpperCase();
}
string = string.replace(regexp, fn_replaceBy);
//equals string = "something foo bar red foo bar RED red pink foo bar RED red"
The function (fn_replaceBy
) is executed for each match. At the first match, the function immediately returns with the matched string (nothing happens), and a flag is set.
Every other match will be replaced according to the logic as described in the function: Normally, you use $0 $1 $2
, et cetera, to refer back to groups. In fn_replaceBy
, the function arguments equal these: First argument = $0
, second argument = $1
, et cetera.
The matched substring will be replaced by the return value of function fn_replaceBy
. Using a function as a second parameter for replace
allows very powerful applcations, such as an intelligent HTML parser.
See also: MDN: String.replace > Specifying a function as a parameter
-
I wasn't convinced the "intelligent HTML parser" wasn't going to link to the "parse HTML using regex" answer, haha. But very nice answer, this was just what I needed. :) – henrebotha Jun 20 '16 at 09:46
It's not the prettiest solution, but you could replace the first occurrence with something arbitrary (like a placeholder) and chain replacements to fulfill the rest of the logic:
'-98324792u4234jkdfhk.sj.dh-f01' // construct valid float
.replace(/[^\d\.-]/g, '') // first, remove all characters that aren't common
.replace(/(?!^)-/g, '') // replace negative characters that aren't in beginning
.replace('.', '%FD%') // replace first occurrence of decimal point (placeholder)
.replace(/\./g, '') // now replace all but first occurrence (refer to above)
.replace(/%FD%(0+)?$/, '') // remove placeholder if not necessary at end of string
.replace('%FD%', '.') // otherwise, replace placeholder with period
Produces:
-983247924234.01
This merely expands on the accepted answer for anyone looking for an example that can't depend on the first match/occurrence being the first character in the string.

- 730
- 10
- 21
"l 5 0 l 0 10 l -5 0 l 0 -10".replace(/^\s+/, '').replace(/\s+l/g, '')
makes sure the first 'l'
is not preceded by space and removes any space followed by an 'l'
.

- 118,113
- 30
- 216
- 245
I found this solution at https://www.regextester.com/99881, using a lookbehind pattern:
/(?<=(.*l.*))l/g
Or more generally
/(?<=(.*MYSTRING.*))MYSTRING/g
where MYSTRING
is something that you want to remove.
(This may also be a useful string for removing all but the first occurrence of "Re:" in an email subject string, by the way.)

- 962
- 8
- 15
-
1Variable length lookbehind is not supported by all regex flavor. In Javascript, lookbehind is not supported by all browsers. – Toto Apr 28 '20 at 10:38
Something like this?
"l 5 0 l 0 10 l -5 0 l 0 -10".replace(/[^^]l/g, '')

- 24,812
- 9
- 57
- 70
-
3Although this does work in this case, doesn't `^` represent the literal character in a character class? – pimvdb Oct 31 '11 at 21:37
-
2`[^^]` matches any character besides `'^'`. It does not match zero-characters at any point other than the start of input as you require. `(!/[^^]/.test('^') && /[^^]/.test('x')) === true` – Mike Samuel Oct 31 '11 at 21:41