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?
You can try a negative lookahead, avoiding the start of the string:
/(?!^)l/g
See if online: jsfiddle
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 replacemethod.
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
"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'.
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.
flagged anser is substantially wrong, first occurrence does not imply string start with that pattern.
Something like this?
"l 5 0 l 0 10 l -5 0 l 0 -10".replace(/[^^]l/g, '')
来源:https://stackoverflow.com/questions/7959975/how-to-replace-all-but-the-first-occurrence-of-a-pattern-in-string