Как заменить все, НО первое вхождение шаблона в строку

быстрый вопрос: мой шаблон является строкой svg, и он выглядит как l 5 0 l 0 10 l -5 0 l 0 -10 Чтобы выполнить некоторое сопоставление с привязкой к ссылке, мне нужно прорезать все, кроме первого l. Я знаю, что я могу отбросить их все и поставить l 'upfront, или я могу использовать подстроки. Но я задаюсь вопросом, есть ли там иероглиф regexp javascript для этого?

Ответы

Ответ 1

Вы можете попробовать отрицательный просмотр, избегая начала строки:

/(?!^)l/g

Смотрите, если онлайн: jsfiddle

Ответ 2

Нет JS RegExp, чтобы заменить все-но-в-первом-образном совпадении. Однако вы можете реализовать это поведение, передав функцию в качестве второго аргумента методу replace.

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"

Функция (fn_replaceBy) выполняется для каждого совпадения. В первом совпадении функция немедленно возвращается с совпадающей строкой (ничего не происходит), и устанавливается флаг.
Каждое другое совпадение будет заменено в соответствии с логикой, как описано в функции: Обычно вы используете $0 $1 $2 и т.д., Чтобы ссылаться на группы. В fn_replaceBy аргументы функции равны этим: Первый аргумент = $0, второй аргумент = $1 и т.д.

Подстроенная подстрока будет заменена возвращаемым значением функции fn_replaceBy. Использование функции в качестве второго параметра для replace позволяет использовать очень мощные приложения, такие как интеллектуальный парсер HTML.

См. также: MDN: String.replace > Указание функции как параметра

Ответ 3

 "l 5 0 l 0 10 l -5 0 l 0 -10".replace(/^\s+/, '').replace(/\s+l/g, '')

гарантирует, что первому 'l' не предшествует пробел и удаляет любое пространство, за которым следует 'l'.

Ответ 4

Это не самое красивое решение, но вы можете заменить первое вхождение на что-то произвольное (например, заполнитель) и заменить цепочку, чтобы выполнить остальную логику:

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

Производит:

-983247924234.01

Это просто расширяет принятый ответ для любого, кто ищет пример, который не может зависеть от первого совпадения/вхождения, являющегося первым символом в строке.

Ответ 5

помеченный anser по существу неверен, первое появление не подразумевает начало строки с этого шаблона.

Ответ 6

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

"l 5 0 l 0 10 l -5 0 l 0 -10".replace(/[^^]l/g, '')