2013-05-01 6 views
4

Существует множество способов поиска строки и замены определенной части чем-то другим, но мне бы хотелось, чтобы какой-то ввод был лучшим способом для этого.Заменить определенную часть строки

Возьмем, например, эта строка:

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

Скажем, я хотел бы найти wid= и заменить то, что после того, пока я не встретиться & (первый) или конец, если ни одна строка ,

Можно ли использовать выражение регулярного выражения или обычный поиск в сочетании с индексом первого & после индекса места, где я нашел то, что искал?

+2

Если вы заинтересованы, чтобы найти метод _fastest_ [jsperf.com] (HTTP: // JSPerf .com) - отличное место для экспериментов. – MikeM

ответ

3

Это похоже на идеальное соответствие регулярному выражению. Двигатели Regex оптимизированы для поиска шаблонов в строке, и именно это мы и стремимся сделать здесь. Попытка реплицировать это на родном JavaScript с search() и т. Д., Скорее всего, будет медленнее. Кроме того, регулярное выражение, вероятно, будет легче понять:

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

будет соответствовать wid= плюс то, что следует, до следующего &, если есть.

Например,

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

заменит все wid=<anything> с wid=1234.

Объяснение:

\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 
+0

Могу ли я также получить аргумент, почему регулярное выражение, а не другие способы с '.search()'? – Roland

+0

@ Роланд: Конечно; Я добавил строку в первом абзаце. –

+0

Я вижу, это звучит как разумный аргумент, все, о чем я забочусь, это скорость, поскольку этот процесс может быть осуществлен на сотнях предметов. – Roland

0

Регулярное выражение, кажется, будет лучшим выбором. Предполагая, что строка находится в a,

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

Рассмотрим следующий пример Powershell универсального регулярного выражения. это будет соответствовать все строки, которые имеют по крайней мере 1 письмо и 1 номер:

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

Пример

$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' 

Урожайность

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 

Резюме

С помощью (?<=[?&]wid=) вас обеспечиваются для нахождения расширенного ключа/значения r независимо от того, где он находится в строке запроса.

+0

В качестве краевого случая это решение предотвратит случайное совпадение ключей типа «& name-wid = значение ", если вы использовали параметр границы слова \ b –

0

Вы можете разделить строку запроса после '?' по '&' в массиве (ключ, значение), а затем отредактируйте его и замените все, что хотите.

Что-то вроде этого

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']) 

выходов 180

Я думаю, что что-то подобное будет быстрее, чем регулярное выражение.

3

Я фактически agree with Tim, что регулярное выражение - путь сюда.

Однако причина - не производительность. Это четкость кода.

Сила регулярных выражений - это их выразительность :: как они позволяют выражать шаблоны ясным и сжатым способом. (Конечно, они часто ужасно ругали, поэтому the famous quote подразумевающие они всегда плохо.)

В данном конкретном случае использование indexOf и substring заканчивают тем, что намного быстрее, чем с помощью регулярных выражений:

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

Как правило, писать свою собственную специфическую логику, которая специально с учетом вашей проблемы почти всегда будет опережать использовать более общее решение. Вы освобождаете багаж от функциональности, которую вы не используете; что напрямую переводит на более высокую производительность. (. Помните, что making code faster is the same as making it do less)

В этом случае, если вы действительно хотели пол-общего решения проблемы замены части строки в соответствии с этим рисунком, вы могли бы написать такую ​​функцию:

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); 
} 

Это относительно читаемо. Однако, опять же, я действительно рекомендую подход к регулярному выражению здесь, потому что это понятно, и это почти наверняка не является узким местом производительности.

(. Если вы разбираете миллионы строк, и это на самом деле является узким местом, которое изменяет вещи)

+0

+1: Хорошая точка, но сравнение не совсем справедливо; мое регулярное выражение содержит утверждение о границе слова, которое игнорирует ваша реализация JavaScript. Поэтому вам понадобится еще одна проверка: «match» wid = ', только если предыдущий символ не является буквенно-цифровым»; что, вероятно, не будет отклонять результат к решению регулярного выражения, но это стоит упомянуть. –

+0

@TimPietzcker: Ты прав, это стоит упомянуть. Я пропустил эту часть для краткости ... которую я сейчас понимаю, было глупым решением, так как включение в нее могло бы усилить мою точку зрения на выразительность регулярных выражений. Может быть, я добавлю это сейчас. –

Смежные вопросы