Разделить строку только на первый экземпляр указанного символа
В моем коде я разделил строку на основе _
и захватил второй элемент в массиве.
var element = $(this).attr('class');
var field = element.split('_')[1];
Принимает good_luck
и предоставляет мне luck
. Отлично работает!
Но теперь у меня есть класс, который выглядит как good_luck_buddy
. Как мне заставить javascript игнорировать второй _
и дать мне luck_buddy
?
Я нашел этот var field = element.split(new char [] {'_'}, 2);
в ответе stackoverflow С#, но он не работает. Я попробовал это в jsFiddle...
Ответы
Ответ 1
Используйте скобки для скобок:
"good_luck_buddy".split(/_(.+)/)[1]
"luck_buddy"
Они определяются как
Если separator
содержит скользящие круглые скобки, согласованные результаты возвращается в массив.
Итак, в этом случае мы хотим разбить на _.+
(т.е. разделительный разделитель является подстрокой, начиная с _
) , но также пусть результат содержит некоторую часть нашего разделителя (т.е. все после _
).
В этом примере наш разделитель (совпадение _(.+)
) равен _luck_buddy
, а захваченная группа (внутри разделителя) равна lucky_buddy
. Без скользящей скобки luck_buddy
(совпадение .+
) не включалось бы в массив результатов, как в случае с простым split
, чтобы разделители не были включены в результат.
Ответ 2
Для чего вам нужны регулярные выражения и массивы?
myString = myString.substring(myString.indexOf('_')+1)
var myString= "hello_there_how_are_you"
myString = myString.substring(myString.indexOf('_')+1)
console.log(myString)
Ответ 3
Я избегаю RegExp любой ценой. Вот еще одна вещь, которую вы можете сделать:
"good_luck_buddy".split('_').slice(1).join('_')
Ответ 4
Замените первый экземпляр уникальным заполнителем, а затем отделите его.
"good_luck_buddy".replace(/\_/,'&').split('&')
["good","luck_buddy"]
Это более полезно, когда нужны обе стороны разделения.
Ответ 5
Вы можете использовать регулярное выражение, например:
var arr = element.split(/_(.*)/)
Вы можете использовать второй параметр, который определяет предел разделения.
то есть:
var field = element.split('_', 1) [1];
Дел >
Ответ 6
Javascript String.split
, к сожалению, не имеет возможности ограничить фактическое количество разделов. Он имеет второй аргумент, указывающий, сколько из фактических разделенных элементов возвращается, что не полезно в вашем случае. Решение состояло бы в том, чтобы разбить строку, перенести первый элемент и затем снова присоединиться к остальным элементам::
var element = $(this).attr('class');
var parts = element.split('_');
parts.shift(); // removes the first item from the array
var field = parts.join('_');
Ответ 7
Решение Mark F является удивительным, но оно не поддерживается старыми браузерами. Решение Kennebec является удивительным и поддерживается старыми браузерами, но не поддерживает регулярное выражение.
Итак, если вы ищете решение, которое разбивает вашу строку только один раз, что поддерживается старыми браузерами и поддерживает регулярное выражение, вот мое решение:
String.prototype.splitOnce = function(regex)
{
var match = this.match(regex);
if(match)
{
var match_i = this.indexOf(match[0]);
return [this.substring(0, match_i),
this.substring(match_i + match[0].length)];
}
else
{ return [this, ""]; }
}
var str = "something/////another thing///again";
alert(str.splitOnce(/\/+/)[1]);
Ответ 8
Для начинающих, подобных мне, которые не привыкли к регулярному выражению, это решение обходного решения работало:
var field = "Good_Luck_Buddy";
var newString = field.slice( field.indexOf("_")+1 );
slice() метод извлекает часть строки и возвращает новую строку, а метод indexOf() возвращает позицию первого найденного вхождения указанного значения в строку.
Ответ 9
Это работало для меня в Chrome + FF:
"foo=bar=beer".split(/^[^=]+=/)[1] // "bar=beer"
"foo==".split(/^[^=]+=/)[1] // "="
"foo=".split(/^[^=]+=/)[1] // ""
"foo".split(/^[^=]+=/)[1] // undefined
Если вам также нужен ключ, попробуйте это:
"foo=bar=beer".split(/^([^=]+)=/) // Array [ "", "foo", "bar=beer" ]
"foo==".split(/^([^=]+)=/) // [ "", "foo", "=" ]
"foo=".split(/^([^=]+)=/) // [ "", "foo", "" ]
"foo".split(/^([^=]+)=/) // [ "foo" ]
//[0] = ignored (holds the string when there no =, empty otherwise)
//[1] = hold the key (if any)
//[2] = hold the value (if any)
Ответ 10
Мне нужны две части строки, так что, regex lookbehind поможет мне в этом.
const full_name = 'Maria do Bairro';
const [first_name, last_name] = full_name.split(/(?<=^[^ ]+) /);
console.log(first_name);
console.log(last_name);
Ответ 11
Используйте метод string replace()
с регулярным выражением:
document.body.innerHTML = "good_luck_buddy".replace(/.*?_/, "");
Ответ 12
Здесь один RegExp, который делает свое дело.
'good_luck_buddy' . split(/^.*?_/)[1]
Сначала это заставляет матч начинаться с начала с '^'. Затем он соответствует любому количеству символов, которые не являются "_", другими словами, все символы перед первым "_".
'?' означает, что минимальное количество символов, которые соответствуют целому шаблону, совпадает с '. *?' потому что за ним следует '_', который затем включается в совпадение в качестве последнего символа.
Поэтому этот метод split() использует такую подходящую часть, как "разделитель", и удаляет ее из результатов. Таким образом, он удаляет все, вплоть до первого "_", и дает вам остальное как 2-й элемент результата. Первый элемент - это "", представляющий часть перед соответствующей частью. Это "", потому что матч начинается с начала.
Есть и другие RegExps, которые работают так же, как /_(.*)/, данные Чанду в предыдущем ответе.
Преимущество/^.*?_/заключается в том, что вы можете понять, что он делает, не зная особой роли групп захвата, выполняемых с replace().
Ответ 13
Самое быстрое решение?
Я провел несколько тестов, и это решение выиграло: 1
str.slice(str.indexOf(delim) + delim.length)
// as function
function gobbleStart(str, delim) {
return str.slice(str.indexOf(delim) + delim.length);
}
// as polyfill
String.prototype.gobbleStart = function(delim) {
return this.slice(this.indexOf(delim) + delim.length);
};
Сравнение производительности с другими решениями
Единственным близким соперником была та же строка кода, за исключением использования substr
вместо split
.
Другие решения, которые я пробовал с использованием split
или RegExp
сильно пострадали и были примерно на 2 порядка медленнее. Использование join
по результатам split
, конечно, добавляет дополнительное снижение производительности.
Почему они медленнее? Каждый раз, когда нужно создать новый объект или массив, JS должен запросить кусок памяти у ОС. Этот процесс очень медленный.
Вот некоторые общие рекомендации, если вы гоняетесь за тестами:
- Новые динамические выделения памяти для объектов
{}
или массивов []
(наподобие того, который создает split
) будут стоить очень дорого. - Поиск
RegExp
более сложен и поэтому медленнее, чем поиск строк. - Если у вас уже есть массив, деструктурирование массивов происходит примерно так же быстро, как и их явная индексация, и выглядит потрясающе.
Удаление за пределы первой инстанции
Здесь решение, которое будет нарезать вплоть до n-го экземпляра. Это не так быстро, но по вопросу OP gobble(element, '_', 1)
по-прежнему> в 2 раза быстрее, чем решение RegExp
или split
и может сделать больше:
/*
'gobble', given a positive, non-zero 'limit', deletes
characters from the beginning of 'haystack' until 'needle' has
been encountered and deleted 'limit' times or no more instances
of 'needle' exist; then it returns what remains. If 'limit' is
zero or negative, delete from the beginning only until '-(limit)'
occurrences or less of 'needle' remain.
*/
function gobble(haystack, needle, limit = 0) {
let remain = limit;
if (limit <= 0) { // set remain to count of delim - num to leave
let i = 0;
while (i < haystack.length) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain++;
i = found + needle.length;
}
}
let i = 0;
while (remain > 0) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain--;
i = found + needle.length;
}
return haystack.slice(i);
}
Согласно приведенному выше определению, gobble('path/to/file.txt', '/')
даст имя файла, а gobble('prefix_category_item', '_', 1)
удалит префикс, как в первом решении. в этом ответе.
- Тесты были выполнены в Chrome 70.0.3538.110 на macOSX 10.14.