Roland
Roland

Reputation: 9731

Replace a specific part of a string

There are plenty of ways to search a string and replace a certain part with something else, but I would like some input on which is the best way to do it.

Take for instance this string :

http://ashleyfurniture.scene7.com/is/image/AshleyFurniture/B233-48-OPEN-SD?wid=640&hei=180&fit=fit&align=0,0&qlt=95&resMode=sharp2

Let's say I would like to search for wid= and replace what is after until I meet & (the first one) or the end of the string if none.

Would I use a regex expression or just a regular search in combination with index of the first & after the index of the place where I found what I was searching?

Upvotes: 4

Views: 210

Answers (5)

Dan Tao
Dan Tao

Reputation: 128417

I actually agree with Tim that a regular expression is the way to go here.

However, the reason is not performance. It's code clarity.

The power of regular expressions is their expressiveness: how they allow you to express patterns in a clear and concise way. (Of course, they are often horribly abused, hence the famous quote implying they are always a bad thing.)

In this particular case, making use of indexOf and substring ends up being a lot faster than using a regular expression:

http://jsperf.com/replace-a-specific-part-of-a-string

As a general rule, writing your own specific logic that's custom-tailored to your problem is almost always going to outperform using a more general solution. You shed the baggage of functionality you aren't using; that directly translates to faster performance. (Remember that making code faster is the same as making it do less.)

In this case, if you did want a semi-general solution to the problem of replacing a portion of a string according to this pattern, you might write a function like this:

function replaceBetween(haystack, left, right, replacement) {
  var indexLeft = haystack.indexOf(left);
  var indexRight = haystack.indexOf(right, indexLeft + left.length);
  return haystack.substring(0, indexLeft) + replacement + haystack.substring(indexRight);
}

This is relatively readable. However, again, I actually recommend the regular expression approach here because it is clear, and it is almost certainly not a performance bottleneck.

(If you're parsing millions of strings and this actually is a bottleneck, that changes things.)

Upvotes: 3

Yoan Arnaudov
Yoan Arnaudov

Reputation: 4164

You can split the query string after the '?' by '&' in array (key, value) and then edit it and replace whatever you want.

Something like this

var url = 'http://ashleyfurniture.scene7.com/is/image/AshleyFurniture/B233-48-OPEN-SD?wid=640&hei=180&fit=fit&align=0,0&qlt=95&resMode=sharp2'
var x = url.split("?");
var query = x[1];
var x2 = query.split("&");
var length = x2.length,
    element = null;
for (var i = 0; i < length; i++) {
  x3 = x2[i].split('=');
  res[x3[0]] = x3[1]
}
console.log(res['hei'])

outputs 180

I think something like this will be faster than regex.

Upvotes: 0

Ro Yo Mi
Ro Yo Mi

Reputation: 15010

Consider the following powershell example of a universal regex. this will match all strings which have at least 1 letter and 1 number:

(?<=[?&]wid=)[^&]*

Example

$Matches = @()
$String = 'http://ashleyfurniture.scene7.com/is/image/AshleyFurniture/B233-48-OPEN-SD?wid=640&hei=180&fit=fit&align=0,0&qlt=95&resMode=sharp2'
Write-Host start with 
write-host $String
Write-Host
Write-Host result string
$String -replace '(?<=[?&]wid=)[^&]*', 'NewValue'

Yields

start with
http://ashleyfurniture.scene7.com/is/image/AshleyFurniture/B233-48-OPEN-SD?wid=640&hei=180&fit=fit&align=0,0&qlt=95&resMode=sharp2

result string
http://ashleyfurniture.scene7.com/is/image/AshleyFurniture/B233-48-OPEN-SD?wid=NewValue&hei=180&fit=fit&align=0,0&qlt=95&resMode=sharp2

Summary

By using the (?<=[?&]wid=) you are ensured to find the wid key/value set regardless of where it is in the query string.

Upvotes: 0

Tim Pietzcker
Tim Pietzcker

Reputation: 336468

That does sound like a perfect fit for a regex. Regex engines are optimized for finding patterns in a string, and that's exactly what we're aiming to do here. Trying to replicate that in native JavaScript with search() etc. is most likely going to be slower. Also, a regex will probably be easier to understand:

/\bwid=([^&]*)/

will match wid= plus whatever follows, until the next &, if there is any.

For example,

result = subject.replace(/\bwid=([^&]*)/g, "wid=1234");

would replace all wid=<anything> with wid=1234.

Explanation:

\b     # Start at a word boundary (so we don't match "rowid=" etc.)
wid=   # Match wid=
(      # Match and capture (for later re-use, if necessary):
 [^&]* # Zero or more characters (any character except &)
)      # End of capturing group

Upvotes: 3

dda
dda

Reputation: 6213

A regex seems to be your best bet. Assuming the string is in a,

a.replace(/wid=([^&]+)/,"wid=WHATEVER")

Upvotes: 0

Related Questions