替换字符串的特定部分

时间:2022-09-13 08:44:30

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.

假设我想搜索wid =并替换后面的内容直到我遇到&(第一个)或字符串的结尾(如果没有)。

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?

我会使用正则表达式或只是常规搜索结合索引的第一个索引和我找到我搜索的地方的索引之后吗?

5 个解决方案

#1


3  

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:

这听起来非常适合正则表达式。正则表达式引擎针对在字符串中查找模式进行了优化,这正是我们在此目的所要做的。尝试使用search()等在原生JavaScript中复制它很可能会变慢。此外,正则表达式可能更容易理解:

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

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

将匹配wid = plus后面的内容,直到下一个&,如果有的话。

For example,

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

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

用wid = 1234替换所有wid =

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

#2


3  

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:

在这种特殊情况下,使用indexOf和substring最终比使用正则表达式快得多:

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.)

(如果您正在解析数百万个字符串,而这实际上是一个瓶颈,那就会改变一些事情。)

#3


0  

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

正则表达式似乎是你最好的选择。假设字符串在a中,

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

#4


0  

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

考虑以下PowerShell通用正则表达式的示例。这将匹配所有至少包含1个字母和1个数字的字符串:

(?<=[?&]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.

通过使用(?<= [?&] wid =),无论查询字符串在何处,都可以确保找到wid键/值集。

#5


0  

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.

我认为这样的事情会比正则表达式更快。

#1


3  

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:

这听起来非常适合正则表达式。正则表达式引擎针对在字符串中查找模式进行了优化,这正是我们在此目的所要做的。尝试使用search()等在原生JavaScript中复制它很可能会变慢。此外,正则表达式可能更容易理解:

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

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

将匹配wid = plus后面的内容,直到下一个&,如果有的话。

For example,

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

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

用wid = 1234替换所有wid =

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

#2


3  

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:

在这种特殊情况下,使用indexOf和substring最终比使用正则表达式快得多:

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.)

(如果您正在解析数百万个字符串,而这实际上是一个瓶颈,那就会改变一些事情。)

#3


0  

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

正则表达式似乎是你最好的选择。假设字符串在a中,

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

#4


0  

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

考虑以下PowerShell通用正则表达式的示例。这将匹配所有至少包含1个字母和1个数字的字符串:

(?<=[?&]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.

通过使用(?<= [?&] wid =),无论查询字符串在何处,都可以确保找到wid键/值集。

#5


0  

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.

我认为这样的事情会比正则表达式更快。